概要 :このチュートリアルでは、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外部キー制約と、それらを使用して関連するテーブル間の関係を強制する方法について学習しました。