0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【DB】多様な製品タイプのためのテーブル設計パタン

Last updated at Posted at 2024-05-16

はじめに

この記事では、リレーショナルデータベースで製品データをモデリングするための5つの一般的なアプローチを探り、それぞれの長所と短所を強調し、ニーズに最適なアプローチを選択するためのガイダンスを提供します。

1. 単一テーブル継承 (Single Table Inheritance, STI)

説明:

各製品タイプが必要とする属性を一つのテーブルにまとめて保存する方法です。これにより、製品タイプによって意味のない属性が発生し、多くの属性にNULLが割り当てられます。

長所:

  • 単純で直感的なテーブル構造
  • 実装と理解が容易

短所:

  • 多くのNULL値によるスペースの無駄
  • 特定の製品タイプに対する制約条件を適用するのが難しい
  • 多くの列があるため、パフォーマンスの問題が発生する可能性。

例スキーマ:

CREATE TABLE products (
    id INT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    type VARCHAR(50) NOT NULL,
    size VARCHAR(50),
    color VARCHAR(50),
    weight DECIMAL(10, 2),
    warranty VARCHAR(50),
    expiration_date DATE,
    -- ほとんどNULLとなる他の多くの列
);

2. クラステーブル継承 (Class Table Inheritance, CTI)

説明:

共通属性のためのメインテーブルと、各製品タイプの特定の属性のための追加テーブルを作成して保存する方法です。これにより、より正規化され効率的なスキーマを作成できます。

長所:

  • NULL値が少ないため効率的なストレージ
  • 制約条件とデータの整合性を適用しやすい
  • 管理しやすく、拡張可能

短所:

  • 完全な製品情報を取得するためにJOIN操作が必要
  • 実装がやや複雑

例スキーマ:

-- メインテーブル
CREATE TABLE products (
    id INT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    type VARCHAR(50) NOT NULL
);

-- 追加テーブル
CREATE TABLE product_electronics (
    product_id INT PRIMARY KEY,
    warranty VARCHAR(50),
    voltage VARCHAR(50),
    FOREIGN KEY (product_id) REFERENCES products(id)
);

-- 追加テーブル
CREATE TABLE product_groceries (
    product_id INT PRIMARY KEY,
    expiration_date DATE,
    weight DECIMAL(10, 2),
    FOREIGN KEY (product_id) REFERENCES products(id)
);

3. 具体テーブル継承 (Concrete Table Inheritance, CTI)

説明:

各製品タイプごとに、共通属性と特定の属性の両方を含む別々のテーブルを作成して保存する方法です。

長所:

  • 各製品タイプに対する単純なクエリ
  • 制約条件とデータの整合性を直接適用可能

短所:

  • 共通属性の冗長な保存
  • 複数のテーブルで共通属性を管理および更新するのが難しい

例スキーマ:

CREATE TABLE product_electronics (
    id INT PRIMARY KEY,
    name VARCHAR(255) NOT NULL, -- 共通属性
    warranty VARCHAR(50) NOT NULL, -- 特定属性
    voltage VARCHAR(50) -- 特定属性
);

CREATE TABLE product_groceries (
    id INT PRIMARY KEY,
    name VARCHAR(255) NOT NULL, -- 共通属性
    expiration_date DATE NOT NULL, -- 特定属性
    weight DECIMAL(10, 2) -- 特定属性
);

4. シリアライズされた大容量オブジェクト (Serialized Large Object, LOB)

説明:

共通属性をテーブルに保存し、タイプ別属性をシリアライズされたオブジェクト(例:PostgreSQLのJSON)として別の列に保存します。

長所:

  • 非常に柔軟で、任意の属性を保存可能
  • 単純なテーブル構造

短所:

  • シリアライズされたデータ内の特定の属性をクエリするのが難しい
  • 検証と制約条件を適用するのが難しい

例スキーマ:

CREATE TABLE products (
    id INT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    type VARCHAR(50) NOT NULL,
    attributes JSON -- JSONデーター
);

例JSONデータ:

{
    "warranty": "2 years",
    "voltage": "220V"
}

5. エンティティ属性値 (Entity-Attribute-Value, EAV)

説明:

属性をテーブルの列ではなく行として保存する方法です。製品のためのメインテーブルと、属性を行ごとに保存する別のテーブルがあります。

長所:

  • 非常に柔軟で、属性を簡単に追加可能
  • スキーマ変更なしで新しい属性を追加可能

短所:

  • 制約条件とデータの整合性を適用するのが難しい
  • 複雑で非効率的なクエリ
  • 管理と保守が難しい

例スキーマ:

CREATE TABLE products (
    id INT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    type VARCHAR(50) NOT NULL
);

CREATE TABLE product_attributes (
    product_id INT,
    attribute_name VARCHAR(50),
    attribute_value VARCHAR(255),
    FOREIGN KEY (product_id) REFERENCES products(id)
);

結論

多様な属性を持つ製品のためのデータベーススキーマを設計することは難しい課題であり、アプリケーションの特定の要件を慎重に考慮する必要があります。データをクエリし、管理する方法に応じて、最適なアプローチを選択できます。各方法の長所と短所を理解することで、ニーズに最も適し、アプリケーションが柔軟で効率的に動作するようにするアプローチを選択できます。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?