@AaronDigullaと@ShaneNに同意します。ギャップは無意味です。彼らがする場合 何かを意味します、それは欠陥のあるデータベース設計です。期間。
そうは言っても、これらの穴を埋める必要がある場合は、そして 少なくともMySQL3.23を実行している場合は、TEMPORARYTABLEを使用して新しいIDのセットを作成できます。ここでの考え方は、現在のすべてのIDを順番に選択して、次のような一時的なテーブルにすることです。
CREATE TEMPORARY TABLE NewIDs
(
NewID INT UNSIGNED AUTO INCREMENT,
OldID INT UNSIGNED
)
INSERT INTO NewIDs (OldId)
SELECT
Id
FROM
OldTable
ORDER BY
Id ASC
これにより、NewId列のAUTO INCREMENTプロパティにより、古いIDを新しいIDにマッピングするテーブルが作成されます。これは本質的にシーケンシャルになります。
これが完了したら、「OldTable」内のIDおよびそれが使用する外部キーへの他の参照を更新する必要があります。これを行うには、おそらく、外部キー制約を削除し、テーブル内の参照をOldIdからNewIdに更新してから、外部キー制約を再設定する必要があります。
ただし、何もしない これについて、IDフィールドはレコードを参照することのみを目的として存在し、使用しないことを理解してください。 特定の関連性があります。
更新:IDの更新例を追加
例:
次の2つのテーブルスキーマがあるとします。
CREATE TABLE Parent
(
ParentId INT UNSIGNED AUTO INCREMENT,
Value INT UNSIGNED,
PRIMARY KEY (ParentId)
)
CREATE TABLE Child
(
ChildId INT UNSIGNED AUTO INCREMENT,
ParentId INT UNSIGNED,
PRIMARY KEY(ChildId),
FOREIGN KEY(ParentId) REFERENCES Parent(ParentId)
)
これで、親テーブルにギャップが表示されます。
親と子の値を更新するには、最初にマッピングを使用して一時テーブルを作成します。
CREATE TEMPORARY TABLE NewIDs
(
Id INT UNSIGNED AUTO INCREMENT,
ParentID INT UNSIGNED
)
INSERT INTO NewIDs (ParentId)
SELECT
ParentId
FROM
Parent
ORDER BY
ParentId ASC
次に、値を正しく更新できるように、外部キー制約を無視するようにMySQLに指示する必要があります。次の構文を使用します:
SET foreign_key_checks = 0;
これにより、MySQLは値を更新するときに外部キーチェックを無視しますが、それでも正しい値タイプが使用されます(MySQLリファレンス 詳細については)。
次に、親テーブルと子テーブルを新しい値で更新する必要があります。これには、次のUPDATEステートメントを使用します。
UPDATE
Parent,
Child,
NewIds
SET
Parent.ParentId = NewIds.Id,
Child.ParentId = NewIds.Id
WHERE
Parent.ParentId = NewIds.ParentId AND
Child.ParentId = NewIds.ParentId
これで、すべてのParentId値が、一時テーブルから新しい順序付けされたIDに正しく更新されました。これが完了すると、参照整合性を維持するために外部キーチェックを再開できます。
SET foreign_key_checks = 1;
最後に、リソースをクリーンアップするために一時テーブルを削除します:
DROP TABLE NewIds
そしてそれはそれです。