1

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

4

2 回答 2

0

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

于 2013-03-01T15:09:19.160 回答
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)。更糟糕的是,并发事务可能会更新行,让您的事务默默地覆盖其他事务的值,而不会意识到它们曾经存在过。

于 2013-03-01T17:34:51.830 回答