【问题标题】:Best way of keeping TEXT field unique in MySQL database在 MySQL 数据库中保持 TEXT 字段唯一的最佳方法
【发布时间】:2013-02-24 01:16:11
【问题描述】:

我想让 TEXT 字段的值在我的 MySQL 表中唯一。

经过小型研究,我发现由于性能问题,每个人都不鼓励在 TEXT 字段上使用 UNIQUE INDEX。我现在要使用的是:

1) 创建另一个字段以包含 TEXT 值的哈希 (md5(text_value))

2) 将此哈希字段设为唯一索引

3) 在查询中使用 INSERT IGNORE

此解决方案是否完整、安全且最佳? (在 SO 上找到)

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

【问题讨论】:

  • 使用 VARCHAR(32)CHAR(32) 查看其他主题:stackoverflow.com/questions/247304/… 您可以将此字段设置为 UNIQUE 以及任何您不想要的字段。
  • 对于触发器来说似乎是一项不错的任务。见dev.mysql.com/doc/refman/5.0/en/create-trigger.html
  • 如果您按照上面的建议进行操作,那么您只需手动执行 MySQL 在使用 HASH 创建唯一索引时会执行的操作。而且很可能不会那么快。
  • @0xCAFEBABE 感谢您的指出。您还有其他想法如何解决这个问题吗?
  • 请记住,两个仅在尾随空格数上有所不同的 TEXT 字段通常是唯一哈希,但 TEXT 字段本身的唯一索引会引发重复键错误。

标签: mysql database performance indexing unique


【解决方案1】:

正如我在 cmets 中被问到我将如何解决这个问题,我将其写为回复。

处于这种情况表明应用程序设计存在错误。考虑一下这意味着什么。

您有一段无法提前指定长度的文本,并且可能非常长(最多 64k),但您希望保持其唯一性。想象一下,将如此大量的数据拆分为单独的键,并组成一个复合索引来生成唯一性。这就是你想要做的。对于整数,这将是一个包含 16000 个整数的索引,并加入一个复合索引。

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

我强烈建议以某种方式拆分数据。这不仅使 DBMS 从合并可变长度字符块中解放出来,而且还可能提供在部分数据上生成复合键的可能性。也许您甚至可以为您的数据找到更好的存储解决方案。

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

【讨论】:

    【解决方案2】:

    差不多完成了。有可能会与哈希发生冲突(生日悖论),因此仅 UNIQUE 索引是不够的。

    最好使用散列和比较检查以确保完全安全。

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

    这可以包含在一个 INSERT 或 UPDATE TRIGGER 中——或者甚至可以是一个 STORED PROCEDUR 以便于检查。

    查看this Stack Overflow question 以了解哈希冲突的示例。

    【讨论】:

    • 请记住,如果字符串是遵循某些限制性规则(例如定义自然语言的规则)的有意义的文本,则哈希冲突的可能性会越来越小。
    • @eggyal 我完全同意,非常非常非常小......但并非不可能。
    猜你喜欢
    • 2016-02-12
    • 1970-01-01
    • 1970-01-01
    • 2017-08-15
    • 2017-05-29
    • 2011-06-21
    • 1970-01-01
    • 1970-01-01
    • 2012-03-07
    相关资源
    最近更新 更多