在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,因为它只是一个映射。