Применять уникальные строки в MySQL

У меня есть столик в MySQL у этого есть 3 поля, и я хочу обеспечить уникальность среди двух полей. Вот таблица DDL:

CREATE TABLE `CLIENT_NAMES` (
`ID` int(11) NOT NULL auto_increment,
`CLIENT_NAME` varchar(500) NOT NULL,
`OWNER_ID` int(11) NOT NULL,
PRIMARY KEY  (`ID`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ID поле является суррогатным ключом (эта таблица загружается с ETL). CLIENT_NAME это поле, которое содержит имена клиентов OWNER_ID Идентификатор указывает на владельца клиента.

Я думал, что мог бы обеспечить это с помощью уникального индекса на CLIENT_NAME а также OWNER_ID,

ALTER TABLE `DW`.`CLIENT_NAMES` 
ADD UNIQUE INDEX enforce_unique_idx(`CLIENT_NAME`, `OWNER_ID`);

но MySQL выдает мне ошибку:

Ошибка выполнения команд SQL для обновления таблицы. Указанный ключ был слишком длинным; максимальная длина ключа составляет 765 байт (ошибка 1071)

У кого-то еще есть идеи?

4 ответа

Решение

MySQL не может обеспечить уникальность ключей длиной более 765 байт (и, очевидно, 500 символов UTF8 могут превысить этот предел).

  1. Действительно ли CLIENT_NAME должен иметь длину 500 символов? Кажется немного чрезмерным.
  2. Добавьте новый (более короткий) столбец с хешем (CLIENT_NAME). Получите MySQL для обеспечения уникальности этого хеша.

Вы смотрели на CONSTRAINT ... UNIQUE?

Что-то кажется странным в этой таблице; Я бы подумал о рефакторинге. На что ссылаются ID и OWNER_ID и каковы отношения между ними?

Имеет ли смысл иметь

CREATE TABLE `CLIENTS` (
`ID` int(11) NOT NULL auto_increment,
`CLIENT_NAME` varchar(500) NOT NULL,
# other client fields - address, phone, whatever
PRIMARY KEY  (`ID`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `CLIENTS_OWNERS` (
`CLIENT_ID` int(11) NOT NULL,
`OWNER_ID` int(11) NOT NULL,
PRIMARY KEY  (`CLIENT_ID`,`OWNER_ID`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Я бы действительно избегал добавления уникального ключа, такого как этот, в строку из 500 символов. Намного эффективнее обеспечить уникальность двух целых чисел, плюс идентификатор в таблице должен действительно ссылаться на то, что требует идентификатора; в вашей версии ID Поле, похоже, идентифицирует только отношения клиент / владелец, которым действительно не нужен отдельный идентификатор, так как это просто отображение.

Здесь Для кодировки UTF8 MySQL может использовать до 3 байтов на символ. CLIENT_NAME имеет размер 3 x 500 = 1500 байт. укорачивать CLIENT_NAME до 250

позже: +1 для создания хэша имени и использования его в качестве ключа.

Другие вопросы по тегам