在MySQL中强制执行唯一行
时间:2020-03-06 14:20:00 来源:igfitidea点击:
我在" 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是代表客户所有者的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)
其他人有什么想法吗?
解决方案
我们是否看过CONSTRAINT ... UNIQUE?
MySQL无法对超过765个字节的键实施唯一性(显然,500个UTF8字符可以超过此限制)。
- CLIENT_NAME是否真的需要500个字符长?似乎有点过分了。
- 添加一个新的(较短的)列,该列为哈希(CLIENT_NAME)。获取MySQL,以在该哈希上强制执行唯一性。
这里。对于UTF8字符集,MySQL每个字符最多可以使用3个字节。 CLIENT_NAME是3 x 500 = 1500字节。将" CLIENT_NAME"缩短为250。
以后:+1创建名称的哈希并将其用作键。
这张桌子有些奇怪。我实际上会考虑对其进行重构。 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个字符串上添加类似的唯一键。在两个int上强制唯一性要高效得多,而且表中的id实际上应该引用需要id的东西;在版本中," ID"字段似乎仅标识客户/所有者关系,实际上它不需要映射ID,因为它只是一个映射。