2013-03-08 142 views
3

我想在我的MySQL表中使TEXT字段的值唯一。在MySQL数据库中保持TEXT字段唯一的最佳方式

经过小型研究后,我发现每个人都因为性能问题而对TEXT字段使用UNIQUE INDEX感到沮丧。我想现在用的就是:

1)创建另一个字段包含文本值(MD5(TEXT_VALUE))

2)的散列使这个哈希领域独树一帜指数

3)使用INSERT忽略在查询中

此解决方案是否完整,安全和最佳? (在SO上发现它)

有没有更好的方法来实现这一目标?

+1

使用'VARCHAR(32)'或'CHAR(32)' 请参阅其他主题:http://stackoverflow.com/questions/247304/mysql-what-data-type-to-use-for-hashed-密码字段和什么长度你可以使这个领域独特和任何你想要的。 – JoDev 2013-03-08 13:24:03

+0

@JoDev谢谢 – 2013-03-08 13:26:22

+1

似乎是一个很好的触发任务。请参阅http://dev.mysql.com/doc/refman/5.0/en/create-trigger.html – Ghigo 2013-03-08 13:27:03

回答

1

差不多完成了。有一个机会(生日悖论)会发生与散列的冲突,因此单独使用UNIQUE索引是不够的。

你最好使用散列和比较检查来完全安全。

SELECT COUNT(*) FROM table 
WHERE md5hash = MD5(text) 
AND textvalue = text 

这可以被包裹成一个INSERT或UPDATE触发器 - 或者甚至为便于检查存储再修改。

查看this Stack Overflow question查看散列冲突的示例。

+0

请记住,如果字符串是遵循一些限制性规则(例如那些定义自然语言的规则)的有意义的文本,则散列冲突的概率变得越来越小。 – eggyal 2013-03-08 14:16:05

+0

@eggyal我完全同意,非常非常小......但并非不可能。 – Steve 2013-03-08 14:18:05

3

正如我在评论中被问到我会如何解决这个问题,我会写它作为回应。

在这种情况下,应用程序设计中会出现错误。考虑这意味着什么。

你有一个文本,你不能提前指定长度,哪一个可以是非常长的(高达64K),其中你想保持唯一性。想象一下如此大量的数据拆分成单独的键,并组合一个复合索引来生成唯一性。这就是你想要做的。对于整数,这将是一个16000个整数的索引,并加入一个复合索引。

进一步考虑CHARACTER类型字段(CHAR,VARCHAR,TEXT)通过编码进行的深层解释,这进一步复杂化了这个问题。

我强烈建议以某种方式分割数据。这不仅可以使DBMS免受可变长度字符块的影响,而且还可以为部分数据生成复合键。也许你甚至可以为你的数据找到更好的存储解决方案。

如果您有任何疑问,我建议发布表格和/或数据库结构,并解释TEXT字段包含的逻辑数据,以及为什么您认为它需要是唯一的。

相关问题