如何在父表中存储记录的id而不是文本

时间:2013-03-01 15:05:40

标签: database database-design relational-database database-schema

我必须得到用户关于他们技能的意见。我有一个技能表,其中id为主键。在另一个表中,我将用户ID和技能ID存储为多对多关系。现在的问题是我怎么知道用户输入的技能已经在我的技能表中了?因为我必须在多对多关系表中放入技能Id。我是每次运行select语句还是有一些有效的解决方案?谢谢,

2 个答案:

答案 0 :(得分:0)

这个问题没有一步到位的解决方案。首先,您需要检查技能表中是否存在技能并获取ID或插入ID,如果不存在则获取ID。然后在PeopleSkills表中插入一行,其中包含人员和技能的ID ......

答案 1 :(得分:0)

  

我怎么知道用户输入的技能已经在我的技能表中了?

并发环境中,您无法知道这一点。即使您执行SELECT,它也只会告诉您SELECT执行时是否存在行 - 它不会告诉您该行是否存在现在。例如,即使SELECT返回空结果,并发事务也可能在接收SELECT结果所花费的几毫秒内插入该行。

所以你要么大幅减少并发(例如通过表锁),要么学会忍受它...

仅需要INSERT时

我建议您只需尝试INSERT(不使用SELECT),然后忽略可能的PRIMARY KEY违规 1

如果您执行了单独的SELECT和INSERT步骤,您仍然必须为PK违规做好准备,因为并发事务可以在SELECT之后但在INSERT之前执行INSERT(和提交)。那么为什么要首先考虑SELECT?

当需要INSERT或UPDATE时

如果联结表包含除FK字段之外的其他字段,那么您可能希望将它们更新为新值,因此您必须首先执行SELECT以确定该行是否需要插入或更新。

在这种情况下,请考虑使用SELECT ... FOR UPDATE(或等效语法)提前锁定行。 2 或者,某些DBMS提供“插入或更新”(又名“UPSERT”)在一个命令中(例如:MySQL INSERT ... ON DUPLICATE KEY UPDATE)。


1 但要注意忽略PK违规 - 不要盲目“吞下”FK或CHECK违规等......

2 为了避免在你有机会更新之前将其删除(仍然可以进行INSERT PK违规)。更糟糕的是,并发事务可能会更新行,使您的事务静默覆盖其他事务的值,而不会意识到它们曾在那里。