【完全ガイド】SQL Server、Oracle、PostgreSQLにおける外部キー設定

2024-04-02

外部キーが NULL および/または重複する場合

外部キーとは?

外部キーは、複数のテーブル間でデータの関連性を定義するものです。親テーブルの主キー列を参照し、子テーブルの列に格納されます。

NULL 値と重複許可

外部キーは、以下の 2 つの観点から設定できます。

  • NULL 値の許可: 子テーブルの列に NULL 値を格納できるかどうか。

各データベースにおける動作

データベースNULL 値の許可重複許可デフォルト設定
SQL Server許可許可NULL 値と重複を許可
Oracle許可許可NULL 値と重複を許可
PostgreSQL制限あり制限ありNULL 値と重複を許可しない

詳細解説

    • 子テーブルのレコードが親テーブルのレコードに関連付けられていない場合に NULL 値を使用できます。
    • 外部キー列に NULL 値が格納されている場合、子テーブルのレコードは親テーブルのレコードと関連付けられていないことを意味します。
  • 重複許可

    • 子テーブルの複数のレコードが同じ親テーブルのレコードを参照できる場合に有効です。
    • 1 対多の関係性において、子テーブルのレコードが複数の親テーブルのレコードに関連付けられる場合に有効です。

各設定の利点と欠点

    • 利点: データの挿入と更新が容易
    • 欠点: データ整合性の問題が発生する可能性
    • 利点: データ整合性を保ちやすい

実用的な例

設定時の注意点

  • データベースの要件に基づいて適切な設定を選択する必要があります。
  • 設定によってデータ整合性やデータ操作の複雑さに影響が出ることがあります。



CREATE TABLE dbo.Customers (
  CustomerID int NOT NULL IDENTITY(1,1) PRIMARY KEY,
  FirstName varchar(50) NOT NULL,
  LastName varchar(50) NOT NULL,
  OrdersID int NULL,
  FOREIGN KEY (OrdersID) REFERENCES dbo.Orders (OrderID)
);

CREATE TABLE dbo.Orders (
  OrderID int NOT NULL IDENTITY(1,1) PRIMARY KEY,
  OrderDate datetime NOT NULL,
  CustomerID int NOT NULL,
  FOREIGN KEY (CustomerID) REFERENCES dbo.Customers (CustomerID)
);

Oracle

CREATE TABLE customers (
  customer_id number(10) NOT NULL,
  first_name varchar2(50) NOT NULL,
  last_name varchar2(50) NOT NULL,
  orders_id number(10) NULL,
  FOREIGN KEY (orders_id) REFERENCES orders (order_id)
);

CREATE TABLE orders (
  order_id number(10) NOT NULL,
  order_date date NOT NULL,
  customer_id number(10) NOT NULL,
  FOREIGN KEY (customer_id) REFERENCES customers (customer_id)
);

PostgreSQL

CREATE TABLE customers (
  customer_id serial PRIMARY KEY,
  first_name text NOT NULL,
  last_name text NOT NULL,
  orders_id integer NULL,
  FOREIGN KEY (orders_id) REFERENCES orders (order_id)
);

CREATE TABLE orders (
  order_id serial PRIMARY KEY,
  order_date date NOT NULL,
  customer_id integer NOT NULL,
  FOREIGN KEY (customer_id) REFERENCES customers (customer_id)
);
  • 2 つのテーブル (CustomersOrders) を作成します。
  • Customers テーブルの OrdersID 列は Orders テーブルの OrderID 列を外部キーとして参照します。
  • 外部キーの NULL 値と重複許可は、各データベースの設定に従います。

サンプルコードの利用方法

  • 上記のサンプルコードをそれぞれのデータベース環境で実行することで、外部キーを設定したテーブルを作成できます。
  • サンプルコードを参考に、実際のデータモデルに合わせてテーブルを作成してください。
  • 外部キーの設定は、データの整合性を保つために重要な役割を果たします。
  • 各データベースにおける外部キーの動作の違いを理解し、適切な設定を選択する必要があります。



外部キーの NULL 値と重複を制御するその他の方法

CHECK 制約を使用して、外部キー列の値に制限を設けることができます。

例:

ALTER TABLE Customers
ADD CONSTRAINT chk_OrdersID CHECK (OrdersID IS NULL OR EXISTS (SELECT 1 FROM Orders WHERE OrderID = Customers.OrdersID));

この制約は、Customers テーブルの OrdersID 列が NULL 値であるか、Orders テーブルに存在する値であることを保証します。

DEFAULT 制約を使用して、外部キー列のデフォルト値を設定できます。

ALTER TABLE Customers
ADD CONSTRAINT def_OrdersID DEFAULT (NULL) FOR OrdersID;

この制約は、Customers テーブルの OrdersID 列に値が設定されていない場合、NULL 値を挿入します。

UNIQUE 制約を使用して、外部キー列に重複を許可しないようにできます。

ALTER TABLE Customers
ADD CONSTRAINT uq_OrdersID UNIQUE (OrdersID);

トリガーを使用して、外部キー列の値が変更された際に処理を実行できます。

CREATE TRIGGER trg_Customers_OrdersID
ON Customers
AFTER UPDATE
AS
BEGIN
  IF (NEW.OrdersID IS NOT NULL)
  BEGIN
    IF NOT EXISTS (SELECT 1 FROM Orders WHERE OrderID = NEW.OrdersID)
    BEGIN
      RAISE ERROR 'OrdersID does not exist.';
    END;
  END;
END;
  • シンプルな方法で外部キーの NULL 値と重複を制御したい場合は、CHECK 制約または DEFAULT 制約を使用するのがおすすめです。
  • より複雑な要件を満たしたい場合は、UNIQUE 制約またはトリガーを使用する必要があります。

sql sql-server oracle


SQL パーセンテージ 計算 方法 集計関数 ウィンドウ関数 CASE式

単純な割合2つの数値の割合を計算するには、次の式を使用できます。例えば、あるテーブルに sales と total_sales という2つの列があり、sales が 100 で total_sales が 1000 の場合、次の式を使用して sales の割合を計算できます。...


SQL Server で重複なしの最初の行だけを取得する3つの方法

DISTINCT 句を使用するDISTINCT 句は、SELECT ステートメントで選択された列から重複する値を削除するために使用されます。 これにより、各一意の値の最初の行のみが選択されます。例:このクエリは、商品 テーブル内のすべての商品名から重複を削除し、各商品名の最初の行のみを返します。...


MySQL、SQL、MariaDBにおけるSELECTにおけるアスタリスク(*)の使用とその他の列の排除

MySQL、SQL、MariaDBなどのデータベース言語において、SELECT句でアスタリスク()を使用すると、そのテーブルのすべての列を選択できます。しかし、このアスタリスク()の使用は、明示的に列を指定した場合と比べていくつかの利点と欠点があります。...


SQL Output 句で挿入されない列を返す:詳細解説とサンプルコード

詳細説明:OUTPUT 句は、INSERT、UPDATE、または DELETE ステートメントと組み合わせて使用し、操作の影響を受けた行の情報を結果セットに含めることができます。この句は、挿入、更新、削除された行だけでなく、トリガーやチェック制約によって変更された列の値も含めて返せます。...


PostgreSQL ARRAY_AGGでNULL値を除外する:上級者向けテクニック

この問題を解決するには、以下の2つの方法があります。FILTER句を使用すると、ARRAY_AGGで処理する前にNULL値を除外できます。例COALESCE関数を使用すると、NULL値を別の値に置き換えることができます。NULL値を完全に除外したい場合は、FILTER句を使用します。...


SQL SQL SQL SQL Amazon で見る



パフォーマンスも考慮!MySQLにおけるNULLと空文字列の使い分け

MySQLデータベースで値を挿入する場合、NULLと空文字列のどちらを使用すべきか迷うことがあります。一見同じように見えて、実は異なる意味を持つため、適切な使い分けが重要です。このガイドでは、それぞれの違い、適切な使用例、およびパフォーマンスへの影響について詳しく説明します。


SQL 外部キーと NULL に関するベストプラクティス

SQL、MySQL、データベースにおける、外部キーを持つテーブル列が NULL にできるかどうかについて解説します。外部キーを持つテーブル列は、状況によって NULL を許可できます。詳細外部キー制約は、子テーブルの列と親テーブルの列を関連付けるデータベースの制約です。この制約により、子テーブルの各行は、親テーブルの既存の行を参照する必要があります。