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 EXTENSION citext SCHEMA ext;
Настройка
Настройка не требуется.
Использование модуля
Пример использования:
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)
Ссылки на документацию разработчика
Исходная документация PosgreSQL модуль citext: https://www.postgresql.org/docs/15/citext.html