#sql #constraints #h2
Вопрос:
Есть ли способ создать уникальный индекс без учета регистра для столбца в таблице H2? Как бы то ни было, я могу сделать это в Postgres с помощью:
create unique index unique_name_idx on my_table (UPPER(name));
Комментарии:
1. Возможно, тип данных VARCHAR_IGNORECASE и уникальный индекс?
2. @jarlh Я думаю, что ваше решение лучше, чем мое. Вероятно, это должен быть общепринятый ответ.
Ответ №1:
H2 допускает только добросовестные столбцы таблицы в качестве компонентов индекса. Он не допускает выражений в них, как это делают PosgreSQL и другие СУБД более высокого уровня.
Однако вы можете проиндексировать вычисляемый столбец в качестве обходного пути. Например:
create table t (
id int,
name varchar(20),
uname varchar(20) as upper(name)
);
create unique index ix1 on t (uname);
insert into t (id, name) values
(1, 'Chicago'),
(2, 'Montreal'),
(3, 'Monterrey');
Затем, если вы попытаетесь вставить:
insert into t (id, name) values
(4, 'montreal');
Он выходит из строя, как и ожидалось:
Ошибка: Нарушение уникального индекса или первичного ключа: «IX1 В ЗНАЧЕНИЯХ PUBLIC.T(БЕЗ ИМЕНИ) («МОНРЕАЛЬ», 2)»; Инструкция SQL: вставить в значения t (идентификатор, имя) (4, «монреаль») [23505-197] Состояние SQLState: 23505 Код ошибки: 23505
Кроме того, индекс также используется для поиска информации. Например, ниже SELECT
используется индекс, как и ожидалось:
explain plan for
select uname from t where uname = 'MONTREAL';
План Выполнения:
SELECT
UNAME
FROM PUBLIC.T
/* PUBLIC.IX1: UNAME = 'MONTREAL' */
WHERE UNAME = 'MONTREAL'
Ответ №2:
Рассмотрите возможность изменения типа данных столбца на VARCHAR_IGNORECASE
(версия VARCHAR без учета регистра).:
ALTER TABLE my_table ALTER COLUMN name VARCHAR_IGNORECASE(20);
Тогда вы можете просто сделать:
create unique index unique_name_idx on my_table (name);
http://h2database.com/html/datatypes.html#varchar_ignorecase_type