1

ユーザーのスキルに関して、ユーザーから意見を得る必要があります。主キーとして id を持つスキルのテーブルがあります。別のテーブルに、ユーザー ID とスキル ID を多対多の関係で格納しています。ここでの問題は、ユーザーが入力したスキルが既に自分のスキル テーブルにあることをどのように知ることができるかということです。スキルの ID を多対多の関係テーブルに入れる必要があるためです。selectステートメントを実行するたびに実行しますか、それとも効率的な解決策がありますか? ありがとう、

4

2 に答える 2

0

ユーザーが入力したスキルが既に自分のスキル テーブルにあることを確認するにはどうすればよいですか?

並行環境では、それを知る方法はありません。SELECT を実行しても、SELECT の実行時に行が存在したかどうかがわかるだけで、行が現在存在するかどうかはわかりません。たとえば、SELECT が空の結果を返した場合でも、SELECT の結果を受け取るまでにかかった数ミリ秒以内に同時トランザクションが行を挿入した可能性があります。

したがって、同時実行性を大幅に削減するか (テーブル ロックなどを使用)、それを受け入れる方法を学ぶかのどちらかです...

INSERT だけが必要な場合

単に INSERT を (SELECT なしで) 試行し、考えられる PRIMARY KEY 違反を無視することをお勧めします1

SELECT と INSERT のステップを別々に行った場合でも、並行トランザクションは SELECT の後、INSERT の前に INSERT (およびコミット) を実行できるため、PK 違反に備える必要があります。では、そもそもなぜ SELECT を気にする必要があるのでしょうか。

INSERT または UPDATE が必要な場合

ジャンクション テーブルに FK フィールドに加えて他のフィールドが含まれている場合は、それらを新しい値に更新する必要がある場合があるため、最初に SELECT を実行して、行に挿入または更新が必要かどうかを判断する必要があります。

このような場合は、SELECT ... FOR UPDATE (または同等の構文) を使用して行を早期にロックすることを検討してください。2あるいは、一部の DBMS は、単一のコマンドで「挿入または更新」(別名「UPSERT」) を提供します (例: MySQL INSERT ... ON DUPLICATE KEY UPDATE )。


1ただし、PK 違反のみを無視するように注意してください。FK 違反や CHECK 違反などをやみくもに「飲み込む」ことはしないでください。

2 UPDATE する前に削除されるのを避けるため (INSERT PK 違反は引き続き可能です)。さらに悪いことに、同時トランザクションが行を更新し、トランザクションが他のトランザクションの値を知らずに上書きしてしまう可能性があります。

于 2013-03-01T17:34:51.830 に答える
0

この問題に対するワンステップの解決策はありません。まず、Skills テーブルにスキルが存在するかどうかを確認して ID を取得するか、存在しない場合は挿入して ID を取得する必要があります。次に、個人とスキルの ID を含む行を PeopleSkills テーブルに挿入します...

于 2013-03-01T15:09:19.160 に答える