在 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
是一个 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 个字符的字符串上添加像这样的唯一键。在两个 int 上强制唯一性会更有效,而且表中的 id 应该真正引用需要 id 的内容;在你的版本中, ID
字段似乎只标识客户/所有者关系,实际上不需要单独的 id,因为它只是一个映射。
这里. 。对于 UTF8 字符集,MySQL 每个字符最多可以使用 3 个字节。CLIENT_NAME 为 3 x 500 = 1500 字节。缩短 CLIENT_NAME
至 250。
之后: +1 创建名称的哈希值并将其用作密钥。
不隶属于 StackOverflow