如何在不使用UNIQUE约束的情况下保证MySQL中的行唯一性?

时间:2010-03-16 14:01:23

标签: mysql

我有一些相当简单的要求,但我不确定如何实施它们:

  • 我有多个并发线程运行相同的查询
  • 查询提供'字符串'值 - 如果表中存在,则查询应返回匹配行的id,否则查询应插入'string'值并返回最后插入的id
  • 'string'列是(并且必须是)一个文本列(它大于varchar 255)所以我不能将它设置为唯一 - 必须通过访问机制强制执行唯一性
  • 查询需要采用存储过程格式(不支持MySQL中的表锁)

我如何保证'string'是唯一的?在另一个线程读取并找不到匹配的“字符串”项后,如何防止其他线程写入表?

感谢您的任何建议..

4 个答案:

答案 0 :(得分:1)

如果您确定不能使用数据库约束,则在另一个字段上使用UNIQUE索引,在该字段中存储完整字符串的良好加密哈希值。我猜MD5或SHA1应该足够了。几个源代码管理系统(如Git,Mercurial,Monotone等)依赖极低的哈希冲突可能性。

答案 1 :(得分:0)

您必须在读/写操作上创建同步线程或同步资源,因此当另一个线程正在读取或写入时,将不允许该线程进行读取或写入。

对于字符串,您可以执行“贪婪”查询,例如:

select distinct string from table where ...

Thread第一次执行select时,然后将结果缓存在HashMap或类似的Map中,并在每次Thread访问表以添加行时更新它。 首先,您将检查HashMap是否存在,然后执行查询。如果HashMap存在,您可以检查是否在其中找到了您的字符串。

答案 2 :(得分:0)

您可以选择该文本,如果没有找到,则插入,否则更新。在一次交易中包装所有内容。

答案 3 :(得分:0)

您可以使用

,而不是使用存储例程中不支持的锁定表
START TRANSACTION;

    SELECT * FROM ....

COMMIT;

您只需确保使用InnoDB等交易安全存储引擎。