外部キー制約とチェック制約について

Oracle Master Silver

データベースの整合性を保つためには、制約の利用が重要です。本記事では、外部キー制約とチェック制約について、具体例や図解を交えて詳細に解説します。

💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?

Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?


外部キー制約

外部キー制約(Foreign Key Constraint)は、あるテーブルの列が別のテーブルの主キーや一意キーを参照することを保証する制約です。これにより、リレーションシップを維持し、関連付けられたデータの整合性を保つことができます。

特徴:

  • 子テーブルの値が親テーブルの値に存在することを保証。
  • 親テーブルの行が削除または更新された場合の挙動を指定可能(ON DELETE, ON UPDATE)。
  • 親子関係を視覚的に把握でき、クエリの簡素化に貢献。

サンプルSQL

以下の例では、orders テーブルが customers テーブルを参照しています。

-- 親テーブルの作成
CREATE TABLE customers (
    customer_id NUMBER PRIMARY KEY,
    customer_name VARCHAR2(100)
);

-- 子テーブルの作成
CREATE TABLE orders (
    order_id NUMBER PRIMARY KEY,
    customer_id NUMBER,
    order_date DATE,
    FOREIGN KEY (customer_id) REFERENCES customers(customer_id) ON DELETE CASCADE
);

-- データ挿入
INSERT INTO customers (customer_id, customer_name) VALUES (1, 'Tanaka');
INSERT INTO orders (order_id, customer_id, order_date) VALUES (101, 1, SYSDATE); -- OK

-- データ整合性エラー
INSERT INTO orders (order_id, customer_id, order_date) VALUES (102, 999, SYSDATE); -- エラー: 参照先が存在しない

-- ON DELETE CASCADEの動作確認
DELETE FROM customers WHERE customer_id = 1; -- ordersの関連レコードも削除される

外部キー制約の構造(図解)

以下の図は、customers テーブルと orders テーブル間のリレーションシップを示しています。

+---------------------+      +-------------------+
| customers           |      | orders            |
+---------------------+      +-------------------+
| customer_id (PK)    |<-----| customer_id (FK)  |
| customer_name       |      | order_id (PK)     |
+---------------------+      | order_date        |
                               +-------------------+
【親キーが存在しない値を挿入しようとした時に発生するエラー】

SQL> INSERT INTO orders (order_id, customer_id, order_date) VALUES (102, 999, SYSDATE);
INSERT INTO orders (order_id, customer_id, order_date) VALUES (102, 999, SYSDATE)
*
行1でエラーが発生しました。:
ORA-02291: 整合性制約(TEST1.SYS_C007758)に違反しました - 親キーがありません
【親キーの行を削除した時の動作】

SQL> select * from customers;

CUSTOMER_ID CUSTOMER_NAME
----------- ------------------------------
1 Tanaka

SQL> select * from orders;

ORDER_ID CUSTOMER_ID ORDER_DA
---------- ----------- --------
101 1 25-01-23

SQL> DELETE FROM customers WHERE customer_id = 1; ★削除

1行が削除されました。

SQL> select * from customers;

レコードが選択されませんでした。

SQL> select * from orders;

レコードが選択されませんでした。 ★orders側も削除される

SQL> commit;

コミットが完了しました。

チェック制約

チェック制約(Check Constraint)は、列の値が指定した条件を満たすことを保証する制約です。これにより、特定のビジネスルールをデータベースレベルで強制することが可能です。

特徴:

  • 条件を自由に指定可能。
  • 単一列または複数列に適用可能。
  • 条件に違反するデータは挿入・更新できない。
  • アプリケーションコードの複雑化を防ぎ、メンテナンス性を向上。

サンプルSQL

以下の例では、products テーブルの price 列と stock_quantity 列に制約を適用しています。

-- テーブルの作成
CREATE TABLE products (
    product_id NUMBER PRIMARY KEY,
    product_name VARCHAR2(100),
    price NUMBER CHECK (price > 0),
    stock_quantity NUMBER CHECK (stock_quantity >= 0)
);

-- データ挿入
INSERT INTO products (product_id, product_name, price, stock_quantity)
VALUES (1, 'Laptop', 100000, 10); -- OK

-- データ整合性エラー
INSERT INTO products (product_id, product_name, price, stock_quantity)
VALUES (2, 'Smartphone', -50000, 5); -- エラー: priceが負の値

チェック制約の構造(図解)

以下の図は、products テーブル内で price 列と stock_quantity 列に適用されている条件を示しています。

+-----------------------+
| products             |
+-----------------------+
| product_id (PK)      |
| product_name         |
| price CHECK (price>0)|
| stock_quantity >= 0  |
+-----------------------+
【チェック制約に違反する値を挿入しようとした時に発生するエラー】

SQL> INSERT INTO products (product_id, product_name, price, stock_quantity)
2 VALUES (2, 'Smartphone', -50000, 5);
INSERT INTO products (product_id, product_name, price, stock_quantity)
*
行1でエラーが発生しました。:
ORA-02290: チェック制約(TEST1.SYS_C007759)に違反しました

複数列に適用するチェック制約の例

-- テーブル作成
CREATE TABLE employees (
    emp_id NUMBER PRIMARY KEY,
    salary NUMBER,
    bonus NUMBER,
    CHECK (salary + bonus <= 100000)
);

-- データ挿入例
INSERT INTO employees (emp_id, salary, bonus) VALUES (1, 80000, 15000); -- OK
INSERT INTO employees (emp_id, salary, bonus) VALUES (2, 90000, 20000); -- エラー: 制約違反

外部キー制約とチェック制約の違い

項目外部キー制約チェック制約
目的リレーションシップの整合性を保つ列の値が条件を満たすことを保証
参照先他のテーブルの列テーブル自身の列
条件の自由度制約は参照先の値に限定される条件を自由に指定可能
主な用途テーブル間のリレーションシップビジネスルールの適用

注意点とベストプラクティス

  • 外部キー制約:
    • 親テーブルと子テーブルの挿入順序に注意し、必要に応じてトランザクションを使用しましょう。
    • ON DELETE CASCADE の利用を検討し、手動でのデータ削除の手間を軽減。
    • 大規模データの場合、適切なインデックスを設定してパフォーマンスを確保。
  • チェック制約:
    • 複雑なビジネスロジックはトリガーやアプリケーションで処理し、制約にはシンプルな条件を設定することが推奨されます。
    • 運用環境では制約の変更や削除が困難なため、設計段階での十分な検討が重要です。

まとめ

外部キー制約とチェック制約は、データベースの整合性を保つために欠かせない機能です。それぞれの特徴を理解し、適切に利用することで、堅牢なデータベース設計を実現しましょう。また、制約の設定だけでなく、設計時の要件整理や運用面での注意点も意識することが、成功の鍵となります。

[参考]
Oracle Databaseデータベース管理者ガイド 19c

💰 【PR】Oracleエンジニアの市場価値、調べてみませんか?

Oracleのスキルは需要が高く、特定の資格や経験を持っていると年収が大幅にアップするケースがあります。まずはIT専門のエージェントで非公開求人をチェックしてみませんか?

コメント

タイトルとURLをコピーしました