Обеспечение уникальных строк в MySQL
-
01-07-2019 - |
Вопрос
у меня есть стол в 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).
У кого-то еще есть идеи?
Решение
MySQL не может обеспечить уникальность ключей длиной более 765 байт (и, очевидно, 500 символов UTF8 могут превысить этот предел).
- Действительно ли имя CLIENT_NAME должно содержать 500 символов?Кажется немного чрезмерным.
- Добавьте новый (более короткий) столбец hash(CLIENT_NAME).Вместо этого заставьте MySQL обеспечить уникальность этого хеша.
Другие советы
Вы смотрели ОГРАНИЧЕНИЕ...УНИКАЛЬНЫЙ?
Что-то в этой таблице кажется немного странным;Я бы действительно подумал о его рефакторинге.Что означают 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 к созданию хеша имени и использованию его в качестве ключа.