我有一个MySQL DB,其中从第三个pary源读取一个键(一个字符串)。然而,这些并不总是保证唯一(它们是电影片头)。因此,我需要检查密钥的唯一性,如果不是唯一的,则修改它以使其唯一 - 例如,在密钥的末尾添加增量计数。
这样做的最佳模式是什么?我目前有一个表存储从第三方收到的每个密钥并存储一个计数,所以我这样做:
INSERT INTO MYTABLE(KEY) VALUES(KEY_VAlUE) ON DUPLICATE KEY UPDATE KEY_COUNT = KEY_COUNT + 1
我正在使用jdbcTemplate和keyHolder来检索新(或更新)行的ID。问题是我还需要重新计算。我当然可以进行第二次查询(SELECT)来获取具有该ID的记录。然而,这里的问题是并发性。有可能(尽管不太可能),在我执行SELECT之前,会发生另一个具有相同第三方密钥的INSERT。在这种情况下,计数将再次递增,我将得到错误的计数。
有什么想法吗?
谢谢Richard。
答案 0 :(得分:1)
这样做的最佳模式不是。用这样的字符串键入你的桌子,尤其是你提前知道会发生碰撞的地方,从长远来看,只会让你感到悲伤。只需使用一个无意义的自动增量键。如果需要,您仍然可以按标题编制索引,而不必使用数据。
顺便提一下,我认为在涉及电影片头碰撞时,惯例是将电影的年份附加在括号中,例如: “制片人(1968)”与“制片人(2005)”
答案 1 :(得分:0)
如果您允许系统为任何行创建任意唯一键值(那些未提交为唯一的行),那么,为什么不创建自己的内部代理键,而不是将其修改为唯一。 ,使用自动递增功能(MySQL有没有?),并存储在非唯一列属性中提交的提交密钥。
对所有关系完整性约束使用内部代理键,并仅将提交的密钥用于其他非唯一要求...
答案 2 :(得分:0)
交易。你 使用InnoDB,对吗?你应该是。
然而,电影标题对我来说听起来像是一个糟糕的主键。您是否考虑过添加synthetic primary key,例如自动增量整数?
答案 3 :(得分:0)
我不知道是否有“模式”可以做到这一点,但为什么不简单地使用交易呢?
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;