外部キーを主キーとして使用しても問題ないのか?

2024-04-10

外部キーを主キーとして使用しても問題ありませんか?

外部キーと主キー

  • 主キー: テーブル内の各行を一意に識別する列。重複値は許可されない。
  • 外部キー: 別のテーブルの主キーを参照する列。データ間の関連性を表現するために使用される。

外部キーを主キーとして使用する場合の利点

  • テーブル間の結合が容易になる。
  • データの整合性を維持しやすくなる。
  • 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: 商品ID
    • purchase_date: 購入日

この例では、customer_idcustomers テーブルの主キーであり、orders テーブルの外部キーでもあります。これにより、orders テーブルの各行は customers テーブルの1つの行に関連付けられます。

  • この例では、customers テーブルの customer_idNULL値 を許可しません。これは、外部キーが常に参照先のテーブルの主キーの値を参照する必要があるためです。
  • 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_idemail の組み合わせで主キーを構成
  • 一意性を保証しながら、外部キーをより自然な形で表現できる

database foreign-keys primary-key


インデックスを使いこなして、データベースのパフォーマンスを最大限に引き出す

データベースインデックスには、主に以下の3種類があります。B木インデックス: データを階層的に組織化することで、効率的な検索を実現します。これは、最も一般的なインデックスの種類です。ハッシュインデックス: データをキー値に基づいてハッシュ化することで、特定の値への直接アクセスを実現します。...


データベーススキーマ管理ツール:Aqua Data Studio、SQL Data Management Studio

SQL Server のストアドプロシージャとデータベーススキーマは、ソース管理システム(Git、Subversionなど)で管理することが重要です。ソース管理を使用することで、以下のメリットを得られます。バージョン管理: 過去の変更履歴をすべて追跡できます。...


もうパスワード漏洩の心配なし!データベースのパスワードを安全に守る方法

データベース内のパスワードを安全に保ちつつ、開発者や管理者が容易に変更できるようにするには、いくつかの課題があります。セキュリティ: パスワードは漏洩してはならない機密情報です。攻撃者はパスワードを悪用してデータベースに不正アクセスし、データの盗難、改ざん、破壊を行う可能性があります。...


データベースルックアップテーブルから C# で動的に列挙型を生成する方法

データベースのルックアップテーブルから値を読み込み、それを基に C# で列挙型を自動生成する方法は、柔軟性と保守性を向上させる強力なテクニックです。このアプローチにより、コードをより簡潔に保ち、データベーススキーマの変更に容易に対応することができます。...


トリガーで実現!MySQLにおける変更履歴の自動記録

ビンログを使用するMySQLは、すべてのデータ変更を記録するバイナリログ(binlog)をデフォルトで有効にします。このログは、データベースの復元やポイントインタイムリカバリに使用できます。方法SHOW BINARY LOGS;コマンドを実行して、使用可能なバイナリログファイルを表示します。...