确保 MySQL 密钥的唯一性
我有一个 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。在这种情况下,计数将第二次增加,并且我会得到错误的计数。
有什么想法吗?
谢谢理查德。
I have a MySQL DB where a key (a string) is read from a third pary source. However, these are not always guaranteed unique (they're movie titles). So I need to check for key uniqueness, and if not unique, amend it to make it unique - by adding an incremental count at the end of the key for example.
What's the best pattern to do this? I currently have a table which stores every key received from 3rd party and stores a count, so I do:
INSERT INTO MYTABLE(KEY) VALUES(KEY_VAlUE) ON DUPLICATE KEY UPDATE KEY_COUNT = KEY_COUNT + 1
I am using jdbcTemplate and a keyHolder to retrieve the ID of the new (or updated) row. The problem is I also need to get the count back. I can of course now do a second query (SELECT) to fetch the record with that ID. However the issue here is with concurrency. It is possible (although unlikely), another INSERT with the same third-party key occurs just before I do my SELECT. In this case the count would be incremented a second time and I'll get the wrong count back.
Any ideas?
Thanks Richard.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这样做的最佳模式是不这样做。用这样的字符串来键入你的表,尤其是在你提前知道会发生冲突的情况下,从长远来看只会给你带来悲伤。只需使用一个无意义的自动增量键即可。如果需要,您仍然可以按标题建立索引,并且不必修改数据。
顺便说一句,我认为当涉及到电影标题冲突时,惯例是在括号中附加电影年份,例如“制片人(1968)”与“制片人(2005)”
The best pattern to do this is not to. Keying your table by a string like this, especially where you know ahead of time that there will be collisions, will cause you nothing but grief in the long run. Just use an otherwise-meaningless autoincrement key. You can still index by title if you want, and you don't have to munge your data.
Incidentally, I think that when it comes to movie title collisions, the convention is to append the year of the movie in parentheses, e.g. "The Producers (1968)" versus "The Producers (2005)"
如果您允许系统为任何行创建任意唯一键值(开始时未作为唯一提交的行),那么与其将其修改为唯一,为什么不使用 auto 创建您自己的内部代理键- 递增功能(MySQL 有这个权利吗?),并将提交的键存储在非唯一列属性中。
对所有关系完整性约束使用内部代理键,并且仅将提交的键用于其他非唯一要求...
If you are allowing the system to create arbitrary unique key values for ANY rows (the ones that are not submitted as unique to start with), then, instead of modifying it to be unique, why not create your own internal surrogate key, using auto-incrementing feature (MySQL has that right?), and store the submitted key as it was submitted in a non-unique column attribute.
use the internal surrogate key for all relational integrity constraints, and only use the submitted key for other non-unique requirements...
交易。您正在使用 InnoDB,对吧?你应该是的。
然而,电影标题对我来说听起来像是一个糟糕的主键。您是否考虑过添加合成主键,例如自动增量整数?
Transactions. You are using InnoDB, right? You should be.
However, a movie title sounds like a poor primary key to me. Have you considered adding a synthetic primary key, such as an autoincrement integer?
我不知道是否有一个“模式”可以做到这一点,但为什么不简单地使用事务呢?
I don't know if there's a "pattern" to do this, but why not simply use a transaction?