Guu*_*uus 12 mysql innodb index constraint
我正在尝试创建一个 InnoDB 表,其中包含一个VARCHAR
最多可容纳 3071 个字符的列。我想UNIQUE
对该列的数据实施约束。
MySQL 似乎使用索引强制执行约束。在 InnoDB 中,索引大小似乎被限制为 767 字节 - 对于VARCHAR(3071)
保存数据的列来说还不够。
关于如何让数据库强制数据的唯一性,而不影响最大数据长度或 InnoDB 的使用的任何想法?
Rol*_*DBA 10
你不想要一个巨大的gen_clust_index(内部聚集索引)。即使对于二级索引,这个大小也是非常巨大的。
您可能必须提前使用触发器或存储过程来检查密钥。
您还可以考虑使用该字段执行SHA1函数调用VARCHAR(3071)
。SHA1将返回一个 40 个字符的字段。这个散列可能正是您需要索引的。
假设你有这个
CREATE TABLE mytable
(
id int not null auto_increment,
txt VARCHAR(3071),
primary key (id)
) ENGINE=InnODB;
Run Code Online (Sandbox Code Playgroud)
并且您想UNIQUE
在 txt 上建立索引。尝试SHA1方法
CREATE TABLE mytablenew LIKE mytable;
ALTER TABLE mytable ADD txtsha1 CHAR(40);
ALTER TABLE mytable ADD UNIQUE KEY (txtsha1);
INSERT INTO mytablenew (id,txt,txtsha1)
SELECT id,txt,SHA1(txt) FROM mytable;
Run Code Online (Sandbox Code Playgroud)
然后,数一数
SELECT COUNT(1) FROM mytable;
SELECT COUNT(1) FROM mytablenew;
Run Code Online (Sandbox Code Playgroud)
如果计数相同,恭喜!!!现在你有一个长度为 40 的唯一索引。你可以完成:
ALTER TABLE mytable RENAME mytableold;
ALTER TABLE mytablenew RENAME mytable;
DROP TABLE mytableold;
Run Code Online (Sandbox Code Playgroud)
正如下面的评论中指出的那样,这可能更原子化:
RENAME TABLE mytable TO mytableold, mytablenew TO mytable;
DROP TABLE mytableold;
Run Code Online (Sandbox Code Playgroud)
在您打算拥有这个大列的任何表上执行此操作。您必须记住将数据的SHA1与INSERT
.
重复键的几率是 2 的 1 的 160 次方(即 1.4615016373309029182036848327163e+48。如果我得到确切的数字,我有一天会发布)。
试一试 !!!