복붙노트

[SQL] 합니까 PostgreSQL을 지원 "악센트를 구분"정렬?

SQL

합니까 PostgreSQL을 지원 "악센트를 구분"정렬?

마이크로 소프트 SQL 서버에서는이 같은 쿼리 가능하다는 수단 (데이터베이스, 테이블이나 열에 대한)에 "악센트를 구분"데이터 정렬을 지정하는 것이 가능

SELECT * FROM users WHERE name LIKE 'João'

조아 이름을 가진 행을 찾을 수 있습니다.

나는 그것이 unaccent_string있는 contrib 기능을 사용하여 PostgreSQL의 문자열에서 악센트를 제거 할 수 있다고 알고 있지만, SELECT 위의 작업을 할 수 있도록 PostgreSQL의이 "악센트를 구분"정렬을 지원하는지 궁금하네요.

해결법

  1. ==============================

    1.당신이에 연결하는 것과 완전히 다른 - 그의 unaccent 모듈을 사용합니다.

    당신이에 연결하는 것과 완전히 다른 - 그의 unaccent 모듈을 사용합니다.

    데이터베이스에 한 번에 설치합니다 :

    CREATE EXTENSION unaccent;
    

    오류를 같이 얻을 경우 :

    이 관련 질문에 대해 지시와 같은 데이터베이스 서버에있는 contrib 패키지를 설치합니다 :

    무엇보다도, 그것은 함수 unaccent ()을 (LIKE이 필요하지 않을 것 같다 경우) 당신이 당신의 예를 함께 사용할 수 있습니다.

    SELECT *
    FROM   users
    WHERE  unaccent(name) = unaccent('João');
    

    쿼리의 종류에 대한 인덱스를 사용하려면, 발현에 인덱스를 만들 수 있습니다. 그러나 포스트 그레스는 인덱스에 대한 불변의 기능을 허용합니다. 함수가 동일한 입력에 대해 서로 다른 결과를 반환 할 수있는 경우, 인덱스가 자동으로 중단 할 수 있습니다.

    불행하게도,) (unaccent 만 안정 불변이 아니다. 를 pgsql-버그에 대한이 스레드에 따르면,이 세 가지 이유 때문이다 :

    웹 지시합니다 일부 자습서는 불변의에 기능 변동성을 변경합니다. 이 무차별 방법은 특정 조건에서 휴식 할 수 있습니다.

    다른 사람은 (내가 과거에 자신을했던 것처럼) 간단한 불변의 래퍼 함수를 ​​제안한다.

    명시 적으로 사용되는 사전을 선언하는 두 개의 매개 변수의 불변과 변형을할지 여부를 계속 논쟁이되고있다. 여기 또는 여기에 읽기.

    또 다른 대안에 제공 Github에서 MusicBrainz에 의해 불변 unaccent () 함수 모듈이 될 것이다. 그것을 자신을 테스트하지 않았습니다. 나는 더 나은 아이디어를 가지고 올 것 같아요 :

    이 방법은 다른 주위에 떠있는 솔루션, 안전 등 더 효율적입니다. 하드 와이어드 스키마 규정 사전 기능과 함께 두 매개 변수 폼을 실행 불변 SQL 래퍼 함수를 ​​만든다.

    는 C 함수의 복사본이 아닌 불변의 기능 것 디스 에이블 기능 인라인베이스를 중첩 때문에, (가짜)뿐만 아니라 불변 선언했다. 그것의 유일한 목적은 SQL 함수 래퍼에 사용됩니다. 아니 그 자체로 사용하기위한 것.

    방법은 C 함수의 선언에 사전 하드 와이어가없는 것처럼 세련가 필요합니다. (겠습니까는 C 코드 자체를 해킹해야합니다.)는 SQL 래퍼 함수가을 수행하고 인라인과 표현의 인덱스 두 기능을 할 수 있습니다.

    CREATE OR REPLACE FUNCTION public.immutable_unaccent(regdictionary, text)
      RETURNS text LANGUAGE c IMMUTABLE PARALLEL SAFE STRICT AS
    '$libdir/unaccent', 'unaccent_dict';
    
    CREATE OR REPLACE FUNCTION public.f_unaccent(text)
      RETURNS text LANGUAGE sql IMMUTABLE PARALLEL SAFE STRICT AS
    $func$
    SELECT public.immutable_unaccent(regdictionary 'public.unaccent', $1)
    $func$;
    

    포스트 그레스 9.5 또는 그 이상을 위해 두 기능에서 병렬 SAFE을 삭제합니다.

    공공 당신이 (공개 기본값) 확장을 설치 스키마되고.

    (regdictionary) 명시 적 형식 선언은 악의적 인 사용자에 의한 함수의 오버로드 변종 가상 공격에 대한 방어.

    이전 I는 unaccent 모듈 제공된 STABLE unaccent 함수 ()에 기초 래퍼 함수를 ​​주장. 그 장애인 기능 인라인. 이 버전은 빠른 내가 여기에 이전했다 간단한 래퍼 함수보다 10 배를 실행합니다. 나는 사전도 스키마 규정 될 수 있다는 것을 발견 할 때까지 - 그리고 배 빠른 함수에 SET의 search_path의 = 공공, pg_temp을 제일 먼저 추가 된 버전으로 이미 그. 아직 (포스트 그레스 12) 문서에서 너무 명확하지 않다.

    당신이 C 함수를 만드는 데 필요한 권한이 부족하면 다시 두 번째 최고의 구현에 있습니다 : 모듈이 제공하는 안정의 unaccent () 함수 주위 불변의 기능 래퍼 :

    CREATE OR REPLACE FUNCTION public.f_unaccent(text)
      RETURNS text AS
    $func$
    SELECT public.unaccent('public.unaccent', $1)  -- schema-qualify function and dictionary
    $func$  LANGUAGE sql IMMUTABLE PARALLEL SAFE STRICT;
    

    마지막으로 메이크업을 표현 지수는 빠른 쿼리 :

    CREATE INDEX users_unaccent_name_idx ON users(public.f_unaccent(name));
    

    기능이나 사전에 변경 한 후이 기능을 포함하는 재 작성 인덱스에 기억에서 적절한 주요 릴리스처럼 그 재 작성 인덱스 않을 것 업그레이드 할 수 있습니다. 최근 주요 릴리스는 모든 unaccent 모듈에 대한 업데이트를했다.

    (쿼리 계획이 그것을 사용할 수 있도록) 인덱스에 맞게 쿼리를 적응 :

    SELECT * FROM users
    WHERE  f_unaccent(name) = f_unaccent('João');
    

    당신이 바로 그 표현의 기능이 필요하지 않습니다. 당신은 직접 '조아'와 같은 악센트가없는 문자열이 제공 할 수 있습니다.

    빠른 기능은 훨씬 더 빨리 식 인덱스를 사용하여 쿼리에 번역하지 않습니다. 즉 미리 계산 된 값을 운영하고 있으며 이미 매우 빠릅니다. 그러나 인덱스 유지 관리 및 쿼리는 인덱스 혜택을 사용하지.

    클라이언트 프로그램에 대한 보안은 당신이 필요 스키마 자격이 어떤 인덱스를 사용할 때 입증 된 바와 같이 기능과 사전 이름을 포스트 그레스 10.3 / 9.6.8 등으로 강화되었다. 보다:

    포스트 그레스 9.5 또는 'Œ'나 같은 나이 합자에서는 'ß'유무 수동으로 확장 할 (당신이 필요한 경우), () unaccent 항상 단일 문자를 대체하기 때문에 :

    SELECT unaccent('Œ Æ œ æ ß');
    
    unaccent
    ----------
    E A e a S
    

    당신은 포스트 그레스 9.6에서 unaccent에이 업데이트를 사랑합니다 :

    굵게 강조 광산. 이제 우리는 얻을 :

    SELECT unaccent('Œ Æ œ æ ß');
    
    unaccent
    ----------
    OE AE oe ae ss
    

    LIKE 또는 임의 패턴 ILIKE 들어 PostgreSQL을 9.1 이상에서 모듈 pg_trgm 이것을 조합. 트라이 그램의 GIN (일반적으로 바람직) 또는 GIST 발현 인덱스를 만듭니다. GIN의 예 :

    CREATE INDEX users_unaccent_name_trgm_idx ON users
    USING gin (f_unaccent(name) gin_trgm_ops);
    

    같은 쿼리를 사용할 수 있습니다 :

    SELECT * FROM users
    WHERE  f_unaccent(name) LIKE ('%' || f_unaccent('João') || '%');
    

    GIN 및 GIST 인덱스는 일반 BTREE보다 유지 관리가 더 비싸다 :

    단지 왼쪽 고정 된 패턴에 대한 간단한 해결책이 있습니다. 더 많은 패턴 매칭 및 성능에 대한 :

    pg_trgm 또한 "유사성"(%) 및 "거리"유용한 연산자를 제공한다 ( "-").

    트라이 그램의 인덱스도 ~ 등 간단한 정규 표현식을 지원합니다. ILIKE와 대소 문자를 구분 패턴 매칭 :

  2. ==============================

    2.가지 진 동일하지 않는 한 비교는 동일하게 반환 할 수 있기 때문에 PostgreSQL은 그 (악센트를 구분 여부)와 같은 데이터 정렬을 지원하지 않습니다. 내부적으로는 해시 인덱스 같은 것들에 대한 복잡성을 많이 소개하기 때문이다. 이러한 이유로 자신의 엄격한 의미에서 데이터 정렬은 순서가 아니라 평등에 영향을 미친다.

    가지 진 동일하지 않는 한 비교는 동일하게 반환 할 수 있기 때문에 PostgreSQL은 그 (악센트를 구분 여부)와 같은 데이터 정렬을 지원하지 않습니다. 내부적으로는 해시 인덱스 같은 것들에 대한 복잡성을 많이 소개하기 때문이다. 이러한 이유로 자신의 엄격한 의미에서 데이터 정렬은 순서가 아니라 평등에 영향을 미친다.

    FTS를 들어, unaccent을 사용하여 자신의 사전을 정의 할 수 있습니다,

    CREATE EXTENSION unaccent;
    
    CREATE TEXT SEARCH CONFIGURATION mydict ( COPY = simple );
    ALTER TEXT SEARCH CONFIGURATION mydict
      ALTER MAPPING FOR hword, hword_part, word
      WITH unaccent, simple;
    

    어떤 당신이 할 수있는 다음 기능 인덱스와 인덱스,

    -- Just some sample data...
    CREATE TABLE myTable ( myCol )
      AS VALUES ('fóó bar baz'),('qux quz');
    
    -- No index required, but feel free to create one
    CREATE INDEX ON myTable
      USING GIST (to_tsvector('mydict', myCol));
    

    이제 아주 간단하게 조회 할 수 있습니다

    SELECT *
    FROM myTable
    WHERE to_tsvector('mydict', myCol) @@ 'foo & bar'
    
        mycol    
    -------------
     fóó bar baz
    (1 row)
    

    또한보십시오

    unaccent 모듈은 어윈의 대답 밖으로 그 확인을 위해, FTS 통합하지 않고 그 자체로 사용할 수 있습니다

  3. ==============================

    3.나는 PostgreSQL의 데이터 정렬을위한 기본 운영 체제에 의존 확신합니다. 그것은 새 데이터 정렬을 생성하고 데이터 정렬을 사용자 정의 지원하지 않습니다. 그래도 난, 당신을 위해 할 수있는 것을 얼마나 많은 일을 모르겠어요. (꽤 많이있을 수 있습니다.)

    나는 PostgreSQL의 데이터 정렬을위한 기본 운영 체제에 의존 확신합니다. 그것은 새 데이터 정렬을 생성하고 데이터 정렬을 사용자 정의 지원하지 않습니다. 그래도 난, 당신을 위해 할 수있는 것을 얼마나 많은 일을 모르겠어요. (꽤 많이있을 수 있습니다.)

  4. from https://stackoverflow.com/questions/11005036/does-postgresql-support-accent-insensitive-collations by cc-by-sa and MIT license