добавьте уникальный индекс без учета регистра в столбец h2

#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