У меня есть таблица в 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 выдает ошибку:
Error executing SQL commands to update table. Specified key was too long; max key length is 765 bytes (error 1071)
У кого-то еще есть идеи?






Вы смотрели на КОНСТРЕЙН ... УНИКАЛЬНО?
MySQL не может обеспечить уникальность ключей, длина которых превышает 765 байт (и, очевидно, 500 символов UTF8 могут превысить этот предел).
Здесь. Для кодировки UTF8 MySQL может использовать до 3 байтов на символ. CLIENT_NAME - 3 x 500 = 1500 байт. Сократите CLIENT_NAME до 250.
потом: +1 для создания хэша имени и использования его в качестве ключа.
Сказать, что UTF-8 использует 3 байта / символ, неверно. Как указано на странице, оно может принимать ДО этого значения, и что делает невозможным использование в 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, похоже, идентифицирует только отношения клиент / владелец, которым действительно не нужен отдельный идентификатор, поскольку это просто сопоставление.
Юникод - это кодировка переменной длины. Символы могут иметь размер от одного до четырех байтов, и только исходные 128 символов ASCII кодируются в одном байте.