4

自動インクリメントの主キーを持つテーブルがあります。大量のデータを挿入し、追加のクエリなしでそれぞれのキーを取得したい。

START TRANSACTION;
INSERT INTO table (value) VALUES (x),(y),(z);
SELECT LAST_INSERT_ID() AS last_id;
COMMIT;

MySQL は、すべてのデータが 1 つの連続した順序付けられたフローに挿入されることを保証できるので、各要素の ID を簡単に計算できますか?

id(z) = last_id;
id(y) = last_id - 1;
id(x) = last_id - 2;
4

2 に答える 2

2

トランザクションを開始してからテーブルにデータを挿入すると、そのテーブル全体がそのトランザクションにロックされます (トランザクションの分離レベルやロックのヒントを試してみない限り)。

それが基本的に取引のポイントです。あなたが操作しているものを(とにかく)変更する外部操作を防ぐため。

この種の「テーブル ロック」は、ほとんどの場合のデフォルトの動作です。

異常な状況では、RDBMS に特定のオプションが設定されていることがわかります。これは、「通常の」デフォルト (テーブル ロック) の動作がその特定のインストールで発生するものではないことを意味します。この場合、INSERT ステートメントの一部としてテーブル ロックが必要であることを指定することで、デフォルトをオーバーライドできるはずです。

編集:

私は MS-SQL Server で多くの経験があり、他の多くの RDBMS でまだら模様の経験があります。その間、挿入が特定の順序で発生するという保証は見つかりませんでした。

この理由の 1 つは、INSERT の SELECT 部分が並列に計算される可能性があることです。これは、挿入されるデータが順不同で準備されていることを意味します。

同様に、特に大量のデータが挿入されている場合、RDBMS は、新しいデータがメモリまたはディスク領域の複数のページにまたがることを認識する場合があります。繰り返しますが、これは並列化された操作につながる可能性があります。

私の知る限り、MySQL には row_number() タイプの関数があり、SELECT クエリで指定でき、その結果をデータベースに保存できます。その後、そのフィールド (ユーザーが作成) に依存できますが、自動インクリメント ID フィールド (RDBMS によって作成) には依存できません。

于 2010-09-09T15:52:46.643 に答える
0

私の知る限り、これはほとんどすべての SQL エンジンで機能します。

于 2010-09-09T14:38:38.237 に答える