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

MySQL外部キー制約、カスケード削除

    殺されたカテゴリのメンバーであるためにカスケードによってnuke製品が削除された場合は、外部キーが正しく設定されていません。サンプルテーブルを考えると、次のテーブル設定が必要です。

    CREATE TABLE categories (
        id int unsigned not null primary key,
        name VARCHAR(255) default null
    )Engine=InnoDB;
    
    CREATE TABLE products (
        id int unsigned not null primary key,
        name VARCHAR(255) default null
    )Engine=InnoDB;
    
    CREATE TABLE categories_products (
        category_id int unsigned not null,
        product_id int unsigned not null,
        PRIMARY KEY (category_id, product_id),
        KEY pkey (product_id),
        FOREIGN KEY (category_id) REFERENCES categories (id)
           ON DELETE CASCADE
           ON UPDATE CASCADE,
        FOREIGN KEY (product_id) REFERENCES products (id)
           ON DELETE CASCADE
           ON UPDATE CASCADE
    )Engine=InnoDB;
    

    このようにして、商品またはカテゴリを削除でき、categories_products内の関連するレコードのみが一緒に削除されます。カスケードはツリーの上位に移動せず、親の製品/カテゴリテーブルを削除しません。

    例:

    products: boots, mittens, hats, coats
    categories: red, green, blue, white, black
    
    prod/cats: red boots, green mittens, red coats, black hats
    

    'red'カテゴリを削除すると、categoriesテーブルの'red'エントリと、prod/catsの2つのエントリ'redboots'と'redcoats'のみが停止します。

    削除はそれ以上カスケードされず、「ブーツ」と「コート」のカテゴリを削除しません。

    コメントのフォローアップ:

    カスケード削除がどのように機能するかについては、まだ誤解しています。これらは、「削除時カスケード」が定義されているテーブルにのみ影響します。この場合、カスケードは「categories_products」テーブルに設定されます。 'red'カテゴリを削除した場合、categories_productsでカスケード削除されるレコードは、category_id = redのレコードのみです。 。 'category_id =blue'のレコードにはアクセスせず、そのテーブルに外部キーが定義されていないため、「products」テーブルに移動しません。

    より具体的な例を次に示します。

    categories:     products:
    +----+------+   +----+---------+
    | id | name |   | id | name    |
    +----+------+   +----+---------+
    | 1  | red  |   | 1  | mittens |
    | 2  | blue |   | 2  | boots   |
    +---++------+   +----+---------+
    
    products_categories:
    +------------+-------------+
    | product_id | category_id |
    +------------+-------------+
    | 1          | 1           | // red mittens
    | 1          | 2           | // blue mittens
    | 2          | 1           | // red boots
    | 2          | 2           | // blue boots
    +------------+-------------+
    

    カテゴリ#2(青)を削除するとします:

    DELETE FROM categories WHERE (id = 2);
    

    DBMSは、「categories」テーブルを指す外部キーを持つすべてのテーブルを調べ、一致するIDが2であるレコードを削除します。products_categoriesで外部キー関係のみを定義したためです。 、削除が完了すると、このテーブルになります:

    +------------+-------------+
    | product_id | category_id |
    +------------+-------------+
    | 1          | 1           | // red mittens
    | 2          | 1           | // red boots
    +------------+-------------+
    

    productsで定義された外部キーはありません テーブルなので、カスケードはそこでは機能しません。そのため、ブーツとミトンがリストされています。 「青いブーツ」も「青いミトン」ももうありません。



    1. データベースでCloseが明示的に呼び出されることはありません

    2. MariaDBで値に少なくとも1桁の数字が含まれているかどうかを検出する方法

    3. 2つの異なるテーブルを結合し、重複したエントリを削除します

    4. 問題設計の主要な指標