【问题标题】:Ensuring uniqueness of a MySQL key确保 MySQL 键的唯一性
【发布时间】:2017-03-13 22:03:52
【问题描述】:

我有一个 MySQL 数据库,其中一个键(一个字符串)是从第三方源读取的。然而,这些并不总是保证是唯一的(它们是电影片名)。因此,我需要检查键的唯一性,如果不是唯一的,则对其进行修改以使其唯一 - 例如,通过在键的末尾添加增量计数。

执行此操作的最佳模式是什么?我目前有一个表,它存储从第 3 方收到的每个密钥并存储一个计数,所以我这样做:

INSERT INTO MYTABLE(KEY) VALUES(KEY_VAlUE) ON DUPLICATE KEY UPDATE KEY_COUNT = KEY_COUNT + 1

我正在使用 jdbcTemplate 和 keyHolder 来检索新(或更新)行的 ID。问题是我还需要恢复计数。我现在当然可以进行第二次查询 (SELECT) 以获取具有该 ID 的记录。但是这里的问题是并发性。有可能(尽管不太可能),在我执行 SELECT 之前发生另一个具有相同第三方密钥的 INSERT。在这种情况下,计数将再次增加,我会得到错误的计数。

有什么想法吗?

谢谢理查德。

【问题讨论】:

    标签: mysql jdbctemplate


    【解决方案1】:

    做到这一点的最佳模式是不这样做。用这样的字符串键入你的桌子,特别是在你提前知道会有冲突的地方,从长远来看只会让你感到悲伤。只需使用其他无意义的自动增量键。如果需要,您仍然可以按标题进行索引,而不必修改数据。

    顺便说一句,我认为当涉及到电影标题冲突时,惯例是在括号中附加电影的年份,例如“制片人 (1968)”与“制片人 (2005)”

    【讨论】:

    • 嗨汤姆。是的,我知道并不理想。我想这样做的原因是我有很好的人类可读的 url - 标题被转换为这样的 URL:mysite.com/The_Producers。因此,“The_Producers”是我唯一的数据库密钥,用于从数据库中提取正确的电影信息。我喜欢这一年的建议,谢谢。
    • 你的 URL 和你的主键有什么关系?没有理由必须将它们连接起来。
    【解决方案2】:

    如果您允许系统为任何行创建任意唯一键值(开始时未提交为唯一的行),那么与其将其修改为唯一,不如创建您自己的内部代理键,使用自动递增功能(MySQL 是这样吗?),并将提交的密钥存储在非唯一列属性中。

    对所有关系完整性约束使用内部代理键,仅将提交的键用于其他非唯一要求...

    【讨论】:

      【解决方案3】:

      交易。您正在使用 InnoDB,对吗?你应该是。

      但是,对我来说,电影标题听起来像是一个糟糕的主键。您是否考虑过添加synthetic primary key,例如自增整数?

      【讨论】:

      • 嗨 bobince。是的,我正在使用 InnoDB。交易性可能是我所追求的。我会使用除标题以外的其他内容作为键,但我想要像:mysite.com/my_movie_title 这样的 URL,因此“my_movie_title”必然是键。为建议干杯。
      • 标题可以是唯一键,而不必是 the 主键。无论如何,该 URL 样式看起来很漂亮,但是如果您必须更改/更正电影标题,所有旧的引用和 URL 都会损坏。如果欺骗电影标题很常见(并且在足够大的数据库中它们可能会如此),那么无论如何您最终都会得到“my_movie_title-12”,此时将使用 ID-and-slug 样式 mysite.com/1234/ my_movie_title 似乎没有那么大的劣势。
      • 是的,我认为您可能是对的。可能最容易在标题中编码一个保证唯一的键/ID。
      【解决方案4】:

      我不知道是否有这样做的“模式”,但为什么不简单地使用事务呢?

      START TRANSACTION;
      
      INSERT INTO MYTABLE(KEY) VALUES(KEY_VAlUE) ON DUPLICATE KEY UPDATE KEY_COUNT = KEY_COUNT + 1;
      SELECT KEY_COUNT FROM MYTABLE WHERE KEY=KEY_VALUE;
      
      COMMIT;
      

      【讨论】:

      • 嗨,僵尸。感谢您的建议,我认为这是最好的方法。干杯。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-20
      • 2016-04-21
      • 1970-01-01
      相关资源
      最近更新 更多