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