citext
Тип данных для строк, нечувствительных к регистру.
Схема размещения:
ext.Модуль предоставляет тип данных
citext для строк, нечувствительных к регистру. Сравнивая значения, он вызывает внутри себя функцию lower(). В остальном почти не отличается от типа text.Стандартный способ с использованием функции
lower() при сравнении значений имеет ряд недостатков:- необходимо всегда обрабатывать функцией
lowerстолбец и значение; - для использования индекса необходимо создать функциональный индекс с функцией
lower; - при работе со столбцами типа
UNIQUEилиPRIMARY KEYнеявно создаваемый индекс будет чувствительным к регистру. Соответственно он не сможет использоваться при регистронезависимом поиске, а также не будет обеспечивать уникальность вне учета регистра.
Применение типа данных
citext позволяет исключить вызовы функции lower() в SQL-запросах и позволяет сделать первичный ключ регистронезависимым.Типы
text и citext учитывают локаль. Это означает, что сравнение символов в верхнем и нижнем регистре зависит от правил LC_CTYPE для базы данных. Такое поведение идентично использованию функции lower() в запросах, и поскольку оно реализуется прозрачно типам данных, в самих запросах ничего дополнительно делать не нужно.- Смена регистра символов в
citextзависит от параметраLC_CTYPEвашей базы данных. Принцип, используемый при сравнении значений, определяется на этапе ее создания. Здесь важно учитывать, что сравнение не будет действительно регистронезависимым. Так, если установленное правило сортировки предназначено для одного языка, а в БД имеются данные на разных языках, то пользователи могут получать неожиданные результаты запросов. - Операторы
citextпринимают во внимание явное указаниеCOLLATE, сравнивая строки в нижнем регистре, но изначальное приведение в нижний регистр всегда выполняется согласно параметруLC_CTYPEбазы данных, как если бы указывалосьCOLLATE "default". - Тип
citextне так эффективен, какtext, поскольку функции операторов и функции сравнения для B-дерева должны делать копии данных и переводить их в нижний регистр для сравнения. Кроме того, с типомtextвозможно исключение дубликатов в B-дереве. Тем не менее, регистронезависимое сравнение с использованиемcitextприменяется эффективнее, чем с применениемlower. - Тип
citextмалополезен в ситуациях, когда требуется сравнивать данные без учета регистра в одних контекстах, и с учетом регистра — в других. Когда регистронезависимое сравнение требуется относительно редко, скорее используютtextи вручную вызывают функциюlower. В случаях, когда чаще требуется регистронезависимое сравнение, имеет смысл сохранить данные в столбце типаcitextи приводить их к типуtextдля регитрозависимого сравнения. Для того, чтобы в обоих случаях поиск был быстрым, потребуются два индекса. - Содержащая операторы
citextсхема должна находиться в текущем путиsearch_path(обычно это схемаpublic), в противном случае будут вызываться регистрозависимые операторы для типаtext. - Рекомендуется учитывать преобразование регистра (case mapping) и выравнивание регистра (case folding). Например, в случаях, когда одной букве в верхнем регистре соответствуют две буквы в нижнем регистре, вместо
citextиспользуются недетерминированные правила сортировки.
Пример использования:
CREATE TABLE users ( nick CITEXT PRIMARY KEY, pass TEXT NOT NULL ); INSERT INTO users VALUES ( 'larry', sha256(random()::text::bytea) ); INSERT INTO users VALUES ( 'Tom', sha256(random()::text::bytea) ); INSERT INTO users VALUES ( 'Damian', sha256(random()::text::bytea) ); INSERT INTO users VALUES ( 'NEAL', sha256(random()::text::bytea) ); INSERT INTO users VALUES ( 'Bjørn', sha256(random()::text::bytea) );
Выборка данных по условию:
SELECT * FROM users WHERE nick = 'Larry';
Оператор
SELECT вернет один кортеж, несмотря на то, что в столбец nick записано значение larry, а в запросе фигурирует Larry:nick | pass -------+-------------------------------------------------------------------- larry | \x303a9ace5a8c75b2f528794477d183d0f59a4969e1fca8e332254ed3cea15ad9 (1 row)
Дополнительную информацию по поставляемому модулю citext можно получить по ссылке.