sql >> データベース >  >> RDS >> Mysql

自動インクリメントフィールドの穴を埋める方法は?

    @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
    

    そしてそれはそれです。



    1. このクエリは、コンマ区切りリストSQL Serverを作成するために何をしますか?

    2. C#でバイトまたはショートの代わりにintを使用する必要があるのはなぜですか

    3. EBSR12コンポーネントのバージョンを見つける方法

    4. EEE MMM dd HH:mm:ssZZZyyyy日付形式からjava.sql.Dateへ