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

SQLite外部キー

    概要 :このチュートリアルでは、SQLite外部キー制約を使用して関連するテーブル間の関係を強制する方法を学習します。

    SQLite外部キー制約のサポート

    SQLiteは、バージョン3.6.19以降、外部キー制約をサポートしています。 SQLiteライブラリは、SQLITE_OMIT_FOREIGN_KEYまたはSQLITE_OMIT_TRIGGERのいずれも使用せずにコンパイルする必要があります。

    SQLiteの現在のバージョンが外部キー制約をサポートしているかどうかを確認するには、次のコマンドを使用します。

    PRAGMA foreign_keys;Code language: SQL (Structured Query Language) (sql)

    このコマンドは整数値を返します:1:有効、0:無効。コマンドが何も返さない場合は、SQLiteバージョンが外部キー制約をサポートしていないことを意味します。

    SQLiteライブラリが外部キー制約をサポートしてコンパイルされている場合、アプリケーションはPRAGMA foreign_keysを使用できます。 実行時に外部キー制約を有効または無効にするコマンド。

    外部キー制約を無効にするには:

    PRAGMA foreign_keys = OFF;Code language: SQL (Structured Query Language) (sql)

    外部キー制約を有効にするには:

    PRAGMA foreign_keys = ON;Code language: SQL (Structured Query Language) (sql)

    SQLite外部キー制約の概要

    2つのテーブルから始めましょう:suppliers およびsupplier_groups

    CREATE TABLE suppliers (
    	supplier_id integer PRIMARY KEY,
    	supplier_name text NOT NULL,
    	group_id integer NOT NULL
    );
    
    CREATE TABLE supplier_groups (
    	group_id integer PRIMARY KEY,
    	group_name text NOT NULL
    );Code language: SQL (Structured Query Language) (sql)

    各サプライヤーが唯一のサプライヤーグループに属していると仮定します。また、各サプライヤグループには、ゼロまたは多数のサプライヤが含まれる場合があります。 supplier_groups間の関係 およびsuppliers テーブルは1対多です。つまり、suppliersの各行に対して テーブルでは、supplier_groupsに対応する行があります テーブル。

    現在、suppliersに行を追加するのを防ぐ方法はありません。 supplier_groupsに対応する行がないテーブル テーブル。

    さらに、supplier_groupsの行を削除することもできます suppliersの対応する行を削除または更新せずにテーブル テーブル。これにより、suppliersに孤立した行が残る可能性があります テーブル。

    suppliersの行間の関係を強制するため およびsupplier_groups テーブルでは、外部キー制約を使用します 。

    外部キー制約をsuppliersに追加するには テーブルでは、CREATE TABLEの定義を変更します 上記のステートメントは次のとおりです:

    DROP TABLE suppliers;
    
    CREATE TABLE suppliers (
        supplier_id   INTEGER PRIMARY KEY,
        supplier_name TEXT    NOT NULL,
        group_id      INTEGER NOT NULL,
        FOREIGN KEY (group_id)
           REFERENCES supplier_groups (group_id) 
    );
    Code language: SQL (Structured Query Language) (sql)

    supplier_groups テーブルは親テーブルと呼ばれます 、これは外部キーが参照するテーブルです。 suppliers テーブルは子テーブルとして知られています 、これは外部キー制約が適用されるテーブルです。

    group_id supplier_groupsの列 テーブルは親キーと呼ばれます 、これは、外部キー制約が参照する親テーブルの列または列のセットです。通常、親キーは親テーブルの主キーです。

    group_id suppliersの列 テーブルは子キーと呼ばれます。通常、子キーは親テーブルの主キーを参照します。

    SQLite外部キー制約の例

    まず、supplier_groupsに3行を挿入します テーブル。

    INSERT INTO supplier_groups (group_name)
    VALUES
       ('Domestic'),
       ('Global'),
       ('One-Time');Code language: SQL (Structured Query Language) (sql)

    次に、新しいサプライヤーをsuppliersに挿入します supplier_groupsに存在するサプライヤグループのテーブル テーブル。

    INSERT INTO suppliers (supplier_name, group_id)
    VALUES ('HP', 2);Code language: SQL (Structured Query Language) (sql)

    このステートメントは完全に機能します。

    第三に、新しいサプライヤーをsuppliersに挿入してみてください supplier_groupsに存在しないサプライヤグループを含むテーブル テーブル。

    INSERT INTO suppliers (supplier_name, group_id)
    VALUES('ABC Inc.', 4);Code language: SQL (Structured Query Language) (sql)

    SQLiteは外部キー制約をチェックし、変更を拒否し、次のエラーメッセージを発行しました:

    [SQLITE_CONSTRAINT]  Abort due to constraint violation (FOREIGN KEY constraint failed)Code language: CSS (css)

    SQLite外部キー制約アクション

    supplier_groupsの行を削除するとどうなりますか テーブル? suppliersの対応するすべての行が必要です テーブルも削除されますか?更新操作に対する同じ質問。

    親キーが削除または更新されるたびに外部キー制約がどのように動作するかを指定するには、ON DELETEを使用します またはON UPDATE 次のようなアクション:

    FOREIGN KEY (foreign_key_columns)
       REFERENCES parent_table(parent_key_columns)
          ON UPDATE action 
          ON DELETE action;Code language: SQL (Structured Query Language) (sql)

    SQLiteは次のアクションをサポートしています:

    • SET NULL
    • デフォルトに設定
    • 制限
    • アクションなし
    • カスケード

    実際には、親テーブルの主キーの値は変更されないため、更新ルールはそれほど重要ではありません。より重要なルールはDELETEです 親キーが削除されたときのアクションを指定するルール。

    次の例で各アクションを調べます

    SET NULL

    親キーが変更、削除、または更新されると、子テーブルのすべての行の対応する子キーがNULLに設定されます。

    まず、テーブルsuppliersをドロップして作成します SET NULLを使用する group_idのアクション 外部キー:

    DROP TABLE suppliers;
    
    CREATE TABLE suppliers (
        supplier_id   INTEGER PRIMARY KEY,
        supplier_name TEXT    NOT NULL,
        group_id      INTEGER,
        FOREIGN KEY (group_id)
        REFERENCES supplier_groups (group_id) 
           ON UPDATE SET NULL
           ON DELETE SET NULL
    );
    Code language: SQL (Structured Query Language) (sql)

    次に、いくつかの行をsuppliersに挿入します テーブル:

    INSERT INTO suppliers (supplier_name, group_id)
    VALUES('XYZ Corp', 3);
    
    INSERT INTO suppliers (supplier_name, group_id)
    VALUES('ABC Corp', 3);Code language: SQL (Structured Query Language) (sql)

    3番目に、サプライヤグループID3をsupplier_groupsから削除します。 テーブル:

    DELETE FROM supplier_groups 
    WHERE group_id = 3;Code language: SQL (Structured Query Language) (sql)

    第4に、suppliersからデータをクエリします テーブル。

    SELECT * FROM suppliers;Code language: SQL (Structured Query Language) (sql)

    group_idの値 suppliersの対応する行の列 テーブルがNULLに設定されています。

    デフォルトに設定

    SET DEFAULT actionは、外部キーの値を、テーブルの作成時に列定義で指定されたデフォルト値に設定します。

    group_idの値が supplier_groupsから行を削除した場合、デフォルトはNULLです。 テーブル、group_idの値 NULLに設定されます。

    デフォルト値を割り当てた後、外部キー制約が開始され、チェックが実行されます。

    制限

    RESTRICT アクションでは、親テーブルの親キーの値を変更または削除することはできません。

    まず、suppliersをドロップして作成します RESTRICTを含むテーブル 外部キーgroup_idでのアクション :

    DROP TABLE suppliers;
    
    CREATE TABLE suppliers (
        supplier_id   INTEGER PRIMARY KEY,
        supplier_name TEXT    NOT NULL,
        group_id      INTEGER,
        FOREIGN KEY (group_id)
        REFERENCES supplier_groups (group_id) 
           ON UPDATE RESTRICT
           ON DELETE RESTRICT
    );Code language: SQL (Structured Query Language) (sql)

    次に、テーブルsuppliersに行を挿入します group_id1を使用します。

    INSERT INTO suppliers (supplier_name, group_id)
    VALUES('XYZ Corp', 1);Code language: SQL (Structured Query Language) (sql)

    3番目に、ID1のサプライヤーグループをsupplier_groupsから削除します。 テーブル:

    DELETE FROM supplier_groups 
    WHERE group_id = 1;Code language: SQL (Structured Query Language) (sql)

    SQLiteは次のエラーを発行しました:

    [SQLITE_CONSTRAINT]  Abort due to constraint violation (FOREIGN KEY constraint failed)Code language: CSS (css)

    これを修正するには、最初にsuppliersからすべての行を削除する必要があります group_idを持つテーブル 1:

    DELETE FROM suppliers 
    WHERE group_id =1;Code language: SQL (Structured Query Language) (sql)

    次に、サプライヤグループ1をsupplier_groupsから削除できます。 テーブル:

    DELETE FROM supplier_groups 
    WHERE group_id = 1;Code language: SQL (Structured Query Language) (sql)

    アクションなし

    NO ACTION 外部キー制約をバイパスすることを意味するものではありません。 RESTRICTと同様の効果があります 。

    カスケード

    CASCADE アクションは、親キーを更新または削除するときに、親テーブルから子テーブルに変更を伝播します。

    まず、suppliersを挿入します グループをsupplier_groupsにグループ化します テーブル:

    INSERT INTO supplier_groups (group_name)
    VALUES
       ('Domestic'),
       ('Global'),
       ('One-Time');Code language: SQL (Structured Query Language) (sql)

    次に、テーブルsuppliersをドロップして作成します CASCADEを使用 外部キーgroup_idでのアクション :

    DROP TABLE suppliers;
    
    CREATE TABLE suppliers (
        supplier_id   INTEGER PRIMARY KEY,
        supplier_name TEXT    NOT NULL,
        group_id      INTEGER,
        FOREIGN KEY (group_id)
        REFERENCES supplier_groups (group_id) 
           ON UPDATE CASCADE
           ON DELETE CASCADE
    );Code language: SQL (Structured Query Language) (sql)

    第三に、いくつかのサプライヤーをテーブルsuppliersに挿入します :

    INSERT INTO suppliers (supplier_name, group_id)
    VALUES('XYZ Corp', 1);
    
    INSERT INTO suppliers (supplier_name, group_id)
    VALUES('ABC Corp', 2);Code language: SQL (Structured Query Language) (sql)

    第4に、group_idを更新します Domesticの サプライヤーグループを100に:

    UPDATE supplier_groups
    SET group_id = 100
    WHERE group_name = 'Domestic';Code language: SQL (Structured Query Language) (sql)

    第5に、テーブルsuppliersからデータをクエリします :

    SELECT * FROM suppliers;Code language: SQL (Structured Query Language) (sql)

    ご覧のとおり、group_idの値をご覧ください。 XYZ Corpの列 テーブル内のsuppliers group_idを更新したときに、1から100に変更されました supplier_groups内 テーブル。これは、ON UPDATE CASCADEの結果です。 アクション。

    6番目に、サプライヤグループID2をsupplier_groupsから削除します。 テーブル:

    DELETE FROM supplier_groups 
    WHERE group_id = 2;Code language: SQL (Structured Query Language) (sql)

    第7に、テーブルsuppliersからデータをクエリします :

    SELECT * FROM suppliers;Code language: SQL (Structured Query Language) (sql)

    group_idのサプライヤID2 サプライヤグループID2がsupplier_groupsから削除されたときに、is2が削除されました テーブル。これは、ON DELETE CASCADEの効果です。 アクション。

    このチュートリアルでは、SQLite外部キー制約と、それらを使用して関連するテーブル間の関係を強制する方法について学習しました。


    1. PostgreSQLクライアントライブラリ(libpq)が見つかりません

    2. データベースの削除は、どのトランザクションでも実行する必要はありませんか?

    3. 例を使用してオラクルに自己参加

    4. 列の最大値を持つ行をフェッチします