MySQL:大列的唯一约束


10

我正在尝试创建一个InnoDB表,该表包含VARCHAR最多可容纳3071个字符的列。我想UNIQUE对该列的数据施加约束。

MySQL似乎使用索引来强制执行约束。在InnoDB中,索引大小似乎被限制为767个字节-不足以VARCHAR(3071)容纳存储数据的列。

关于如何在不影响最大数据长度或使用InnoDB的情况下如何使数据库强制数据唯一性的想法?

Answers:


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;

而您想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;

然后算一下

SELECT COUNT(1) FROM mytable;
SELECT COUNT(1) FROM mytablenew;

如果计数相同,恭喜!!!现在,您有了一个长度为40的唯一索引。您可以完成以下操作:

ALTER TABLE mytable RENAME mytableold;
ALTER TABLE mytablenew RENAME mytable;
DROP TABLE mytableold;

如下面的评论所指出的那样,这可能更具原子性:

RENAME TABLE mytable TO mytableold, mytablenew TO mytable;
DROP TABLE mytableold;

在打算使用此大列的任何表上执行此操作。您必须记住要添加数据的SHA1和上的数据INSERT

重复键的几率是160的2分之一(即1.4615016373309029029182036848327163e + 48。如果我得到确切的数字,则有一天会发布它)。

试试看 !!!


+1这基本上是一个好主意!我会把它与一个触发器结合起来,该触发器将检查两个摘要是否相同,内容是否也相同,以及Java中的HashMap的工作原理...
ppeterka 2012年

1
罗兰多-我有很多疑问:(1)sha1应该是ascii,而不是utf8。(2)如果您使用HEX()和UNHEX(),sha1可能是BINARY(20)。(3)要使重命名成为原子的,而不会造成停机,请执行RENAME TABLE mytable TO mytableold,mytablenew TO mytable的重命名。然后,在您感到满意之后,删除表mytableold。(4)引用的赔率是单行的。(5)2 64是错误的-是 2160。(6)表格的几率约为:“在2 53中,有2 53行的表格有一个dup sha1的机会。” (6a)当您在巨型彩票上收集时,您更有可能乘上小行星。
瑞克·詹姆斯

@RickJames指出了所有要点。请原谅我对#5点的错误数学,它是2 ^ 160。我在回答中调整了#3。
RolandoMySQLDBA 2012年

1
伙计们,您提出的赔率假设:1. SHA具有完美的分布;2.输入是完全随机的。SHA没有完善的分布。其他任何哈希算法也不会。输入不是完全随机的,尽管SHA和其他摘要一样,由于输入的任何细微变化都会导致输出的巨大变化,但完全有可能某些输入集会产生相同的输出,并且这些输入具有一些系统的输入他们之间的联系。现在,我主要是咿咿呀呀这里,因为几率非常低的; 但仍然应该警惕。
Shlomi Noach 2012年

@ShlomiNoach哈希键可能很麻烦。按照这个速度,甚至PASSWORD函数是可以接受的(palominodb.com/blog/2011/12/04/hashing-algorithm-mysql-password
RolandoMySQLDBA
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.