外部キーを主キーとして使用しても問題ないのか?
外部キーを主キーとして使用しても問題ありませんか?
外部キーと主キー
- 主キー: テーブル内の各行を一意に識別する列。重複値は許可されない。
- 外部キー: 別のテーブルの主キーを参照する列。データ間の関連性を表現するために使用される。
外部キーを主キーとして使用する場合の利点
- テーブル間の結合が容易になる。
- データの整合性を維持しやすくなる。
- NULL値を許可できない。
- 参照先のテーブルの主キーが変更された場合、参照しているテーブルの外部キーも更新する必要がある。
- 循環参照が発生する可能性がある。
- 顧客テーブル: 顧客ID (主キー)、氏名、住所
- 注文テーブル: 注文ID (主キー)、顧客ID (外部キー)、商品ID、購入日
この例では、顧客IDは顧客テーブルの主キーであり、注文テーブルの外部キーでもあります。これにより、注文テーブルの各行は顧客テーブルの1つの行に関連付けられます。
外部キーを主キーとして使用したサンプルコード
-- 顧客テーブル
CREATE TABLE customers (
customer_id INT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
address VARCHAR(255) NOT NULL
);
-- 注文テーブル
CREATE TABLE orders (
order_id INT PRIMARY KEY,
customer_id INT NOT NULL,
product_id INT NOT NULL,
purchase_date DATE NOT NULL,
FOREIGN KEY (customer_id) REFERENCES customers (customer_id)
);
customers
テーブル:customer_id
: 主キーname
: 顧客名address
: 顧客住所
orders
テーブル:customer_id
:customers
テーブルのcustomer_id
を参照する外部キーproduct_id
: 商品IDpurchase_date
: 購入日
この例では、customer_id
は customers
テーブルの主キーであり、orders
テーブルの外部キーでもあります。これにより、orders
テーブルの各行は customers
テーブルの1つの行に関連付けられます。
- この例では、
customers
テーブルのcustomer_id
は NULL値 を許可しません。これは、外部キーが常に参照先のテーブルの主キーの値を参照する必要があるためです。 customers
テーブルのcustomer_id
を変更する場合は、orders
テーブルのcustomer_id
も更新する必要があります。- 循環参照が発生する可能性があります。例えば、
customers
テーブルにorders_id
という外部キーがあり、orders
テーブルにcustomer_id
という外部キーがある場合、循環参照が発生します。
外部キーを主キーとして使用しない代替方法
サロゲートキーを使用する
サロゲートキーは、テーブル内の各行を一意に識別するために使用される人工的なキーです。サロゲートキーは、自動生成されることが多く、意味を持たないことが一般的です。
-- 顧客テーブル
CREATE TABLE customers (
customer_id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
address VARCHAR(255) NOT NULL
);
-- 注文テーブル
CREATE TABLE orders (
order_id INT PRIMARY KEY AUTO_INCREMENT,
customer_id INT NOT NULL,
product_id INT NOT NULL,
purchase_date DATE NOT NULL,
FOREIGN KEY (customer_id) REFERENCES customers (customer_id)
);
このコードでは、customers
テーブルと orders
テーブルを作成しています。
サロゲートキーを使用する利点は、以下のとおりです。
- 参照先のテーブルの主キーが変更されても、更新する必要がない
- 循環参照が発生しない
複合主キーを使用する
複合主キーは、複数の列で構成される主キーです。
-- 顧客テーブル
CREATE TABLE customers (
customer_id INT NOT NULL,
email VARCHAR(255) NOT NULL,
PRIMARY KEY (customer_id, email)
);
-- 注文テーブル
CREATE TABLE orders (
order_id INT PRIMARY KEY AUTO_INCREMENT,
customer_id INT NOT NULL,
product_id INT NOT NULL,
purchase_date DATE NOT NULL,
FOREIGN KEY (customer_id) REFERENCES customers (customer_id)
);
customers
テーブル:email
: 顧客メールアドレスcustomer_id
とemail
の組み合わせで主キーを構成
- 一意性を保証しながら、外部キーをより自然な形で表現できる
database foreign-keys primary-key