次の3つのテーブルがあります。
products:
product_id,
product_name,
...
categories:
category_id,
category_name,
category_parent_id,
category_priority (for sort ordering),
.....
labels:
label_id,
label_name,
.....
アイデアは、productsがcategoryに割り当てられると、 categorybylabelsによってWebサイトに次のようにリストされます。
---label1---
product_1
product_2
product_3
---label2---
product_4
product_5
---label3---
product_6
product_7
product_8
product_9
etc.
これらすべてを結び付けて、次のような異常を防ぐ関連付けテーブルを設計する方法がわかりません。
---label1---
product_1
product_2
---label2---
product_2
product_3
同時に、ラベルがカテゴリに割り当てられない状況を許可します正当化するのに十分なproductsがない場合。
それをまとめる構造を設計することは可能ですか、それとも「すべての希望を捨てて」次のようなものに行くべきですか?
categories:
category_id,
category_name,
category_parent_id,
categor_is_label,
category_priority
products:
product_id,
product_name,
...
それに続く関連テーブル:
categories_products:
category_id,
product_id,
priority
すべてのロジックを処理し、アプリケーションの異常をチェックしますか?
ユーザーがデータベースに直接アクセスできないと想定しています。
お手元のビジネスコンテキストについての詳細な会話に興味がある方は、 このチャットルーム にアクセスしてください。
注:この回答は、コメントとチャットの対話の最も初期のシリーズによって派生したビジネスルールを具体的にカバーするためのアプローチを示します(そのほとんどは この質問の改訂 それにもかかわらず、より詳細な 明確化と審議 が行われた後、 @yemet は、異なるビジネスルールの連続した識別のために、ビジネスコンテキストが多少異なる方法を必要とする可能性があることを示しました
関心のあるエンティティタイプ(一度実装されたテーブル)に関連する三元関連付け(三元またはひし形関係とも呼ばれます)が存在すると判断したという事実は、あなたは正しい方向に向かっています。
目的は、実装の側面を完全に検討する前に、論理レベル分析から始めて、手元にある3つの異なる関係を個別に処理することです。この点で、関連するビジネスルールを説明するいくつかの定式化を書き留めることは非常に役立ちます。例:
まず、次の多対多(M:N)の関係についてです。
A product is classified by one-to-many categories
A category classifies zero-one-or-many products
これは、私がproduct_category
と呼ぶ連想エンティティタイプの存在を意味します。
次に、明確なM:N関係の場合:
A category is integrated by zero-one-or-many labels
A label integrates zero-one-or-many categories
別の関連エンティティタイプがあることを示唆する状況。この場合は、category_label
という名前にします。
次に、別のM:N関係を管理する時が来ました。今回は、上記で説明した2つの関連エンティティタイプ間の関係です。
A product_category may receive zero-one-or-many label_assignments
A category_label may take part in zero-one-or-many label_assignments
前述のように、label_assignment
と名付けた新しいエンティティタイプを含めましたが、当然、ビジネスドメインに関してより意味のある用語を使用して名前を付けることができます。
質問に含まれているcategories
テーブル(具体的には列categories.category_parent_id
)の構造に基づいて、自己再帰1対多(1 :M)category
というエンティティタイプに関する関係。その後、そのような状況を確認したため、次のルールも適用されます。
A category comprises zero-one-or-many categories
次に、IDEF1Xを導出しました1図1 :
この配置により、次の理由により、ニーズの多くを解決できます。
そのため、次のDDL構造をコーディングしました( SQL Fiddle )でテスト):
-- You should determine which are the most fitting
-- data types and sizes for all your table columns
-- depending on your business context characteristics.
-- As one would expect, you are free to make use of
-- your preferred (or required) naming conventions.
CREATE TABLE product
(
product_id INT NOT NULL,
product_code CHAR(30) NOT NULL,
name CHAR(30) NOT NULL,
description CHAR(90) NOT NULL,
created_datetime DATETIME NOT NULL,
CONSTRAINT PK_product PRIMARY KEY (product_id),
CONSTRAINT AK_product_code UNIQUE (product_code), -- (Possible?) ALTERNATE KEY.
CONSTRAINT AK_product_name UNIQUE (name), -- ALTERNATE KEY.
CONSTRAINT AK_product_description UNIQUE (description) -- ALTERNATE KEY.
);
CREATE TABLE category
(
category_number INT NOT NULL,
parent_category_number INT NULL, -- Set up as ‘NULLable’, in order to focus on the main aspects of the approach exposed.
name CHAR(30) NOT NULL,
description CHAR(90) NOT NULL,
created_datetime DATETIME NOT NULL,
CONSTRAINT PK_category PRIMARY KEY (category_number),
CONSTRAINT AK_category_name UNIQUE (name), -- ALTERNATE KEY.
CONSTRAINT AK_category_description UNIQUE (description), -- ALTERNATE KEY.
CONSTRAINT FK_FROM_category_TO_parent_category FOREIGN KEY (parent_category_number)
REFERENCES category (category_number)
);
CREATE TABLE label
(
label_number INT NOT NULL,
name CHAR(30) NOT NULL,
description CHAR(90) NOT NULL,
created_datetime DATETIME NOT NULL,
CONSTRAINT PK_label PRIMARY KEY (label_number),
CONSTRAINT AK_label_name UNIQUE (name), -- ALTERNATE KEY.
CONSTRAINT AK_label_description UNIQUE (description) -- ALTERNATE KEY.
);
CREATE TABLE product_category -- Associative table.
(
product_id INT NOT NULL,
category_number INT NOT NULL,
classified_datetime DATETIME NOT NULL,
CONSTRAINT PK_product_category PRIMARY KEY (product_id, category_number),
CONSTRAINT FK_FROM_product_category_TO_product FOREIGN KEY (product_id)
REFERENCES product (product_id),
CONSTRAINT FK_FROM_product_category_TO_category FOREIGN KEY (category_number)
REFERENCES category (category_number)
);
CREATE TABLE category_label -- Associative table.
(
category_number INT NOT NULL,
label_number INT NOT NULL,
integrated_datetime DATETIME NOT NULL,
CONSTRAINT PK_category_label PRIMARY KEY (category_number, label_number),
CONSTRAINT FK_FROM_category_label_TO_category FOREIGN KEY (category_number)
REFERENCES category (category_number),
CONSTRAINT FK_FROM_category_label_TO_label FOREIGN KEY (label_number)
REFERENCES label (label_number)
);
CREATE TABLE label_assignment -- Associative table that ‘concretizes’ a relationship between two distinct relationships.
(
product_id INT NOT NULL,
category_number INT NOT NULL,
label_number INT NOT NULL,
assigned_datetime DATETIME NOT NULL,
CONSTRAINT PK_label_assignment PRIMARY KEY (product_id, category_number, label_number), -- Composite PRIMARY KEY.
CONSTRAINT FK_FROM_label_assignment_TO_product_category FOREIGN KEY (product_id, category_number) -- Composite FOREIGN KEY.
REFERENCES product_category (product_id, category_number),
CONSTRAINT FK_FROM_label_assignment_TO_category_label FOREIGN KEY (category_number, label_number) -- Composite FOREIGN KEY.
REFERENCES category_label (category_number, label_number)
);
label_assignment
属性が両方に含まれているため、category_number
テーブルの2つの複合FOREIGN KEY定義に特に注意してください。
次のことを規定する要件を提示しました。
ショップで表示するには、製品をカテゴリに割り当てる必要があります。
したがって、ここで連想テーブルに行を挿入することにより、product
行を挿入するたびにリンク特定のcategory
でそれを確実に挿入する必要があります。 product_category
と呼ばれます。このように、両方の操作は同じ ACID TRANSACTION 内で実行する必要があります。これにより、単一ユニットとして成功または失敗します。
あなたは私の答えを助けるかもしれません
そして @Ypercubeᵀᴹ
1.情報モデリングの統合定義( IDEF1X )は、米国国立標準技術研究所(NIST)によって1993年12月に標準として確立された、非常に推奨されるデータモデリング手法です。 )(a) Relational Model のオリジネーターが作成した理論的研究、つまり Dr. EF Codd ;(b) Entity-Relationship view 、 Dr。PP Chen ;および(c)によって開発された論理データベース設計技法、Robert G. Brownによって開発されました。IDEF1Xが一次論理によって形式化されたことは注目に値します。