複数のテーブルがあります。
それらにはすべて、次のフィールドがあります。
item_title | item_description | item_thumbnail | item_keywords
追加の item_type フィールドを持つ単一の items_table を用意してから、それぞれのテーブルに結合するか、すべてを別々のテーブルに保持する方がよいでしょうか?
複数のテーブルがあります。
それらにはすべて、次のフィールドがあります。
item_title | item_description | item_thumbnail | item_keywords
追加の item_type フィールドを持つ単一の items_table を用意してから、それぞれのテーブルに結合するか、すべてを別々のテーブルに保持する方がよいでしょうか?
文脈によります。アイテムの差別化がほとんどなく、アイテムを分離する必要があるシナリオが 6 か月、12 か月、2 年で発生しないことが確実な場合は、1 つの一般的な「アイテム」テーブルのルートに進みます。特定の項目タイプに特定の要件がある場合は、このデータを含む別のテーブルを作成しLEFT JOIN
、追加のデータを含めるようにクエリを実行するときに を作成できます。
また、他のデータベース タイプを検討することをお勧めします。あなたのシナリオ (保存されたデータの差異がほとんどない多くの項目タイプ) から判断すると、MySQL のようなリレーショナル データ ベースのデータベース エンジンよりも、MongoDB のようなドキュメント ベースのデータベース エンジンの方がメリットがあると思います。
OK、テーブルはフィールドを共有します。それらは制約も共有していますか1 ?
たとえば、テーブルに個別の外部キーがある場合、それらを個別に保持するか、それらを単一のテーブルにマージして、FK を個別に保持することができます。
item_title
item_description
item_thumbnail
item_keywords
table1_id REFERENCES table1 (table1_id)
table2_id REFERENCES table2 (table2_id)
...
CHECK (
(table1_id IS NOT NULL AND table2_id IS NULL ...)
OR (table1_id IS NULL AND table2_id IS NOT NULL ...)
...
)
(注: MySQL は CHECK を強制しないため、トリガーまたはクライアント コードから同等の強制を行うか、可能であれば別の DBMS を使用する必要があります。)
どちらが優れているかを判断するには、データベースについて詳しく知る必要があります。
追加の item_type フィールドを使用して、それぞれのテーブルと結合し、
できる限り、コードで FK を強制しないでください。テーブルをマージする場合でも、FK をマージしないで、代わりに上記のようなことを行います。並行環境 (複数のクライアントが同じデータを同時に変更しようとする可能性がある環境) のコンテキストでコードに FK を適用することは、適切に実行するのが難しく、パフォーマンスも良好です。DBMS に実行させる方がはるかに優れています。
ところで、何item_keywords
ですか?キーワード (または同様のもの) のカンマ区切りのリストである場合は、さらに正規化し、キーワードを独自の別のテーブルに抽出する必要があります。
1ドメイン (データ型と CHECK)、キー (PRIMARY KEY と UNIQUE)、および参照 (FOREIGN KEY) 制約。
私がよく理解していれば、スキーマを正規化するだけで済みます。
アイテム:
item_id
item_name
item_description
アイテムの種類
item_id
type_id
種類
type_id
item_file_name
したがって、このようにして、任意の数のタイプのアイテムをいくつでも持つことができます
これがやりたいの???
次の理由から、アイテム用に 1 つのテーブルを使用し、タイプ用に 1 つのテーブルを使用することをお勧めします (10 個のタイプがあると仮定します)。
基本的に、アイテム用に 1 つのテーブルとタイプ用に 1 つのテーブルがある場合、導入する新しいタイプごとにデータベース スキーマとコードを変更する必要はありません。ただし、タイプの数が少なく、変わらないことが確実な場合は、複数のテーブルの使用を検討できます。
2 つの別個のテーブルを作成し、必要な出力に従ってそれらを結合します。
すなわち>
1.1番目のTABLE (マスターテーブル==>item_type)
item_type(item_type_id,item_type_name,status)
2.2番目のTABLE(子テーブル==>item_details)
item_details(item_id,item_type_id,item_title,item_description,item_thumbnail,item_keywords)
サインテーブルの方が適していると思います。より多くの結合、プログラム(コード)の複雑さ、および複数のテーブルの比較でのエラーを回避します。db クラスタリングなどの管理の観点からも優れています。
同じ繰り返し列を持つ必要がある非常に多くのテーブルがある場合は、共通フィールド用に別のテーブルを作成するのが良い方法です。これらの繰り返される列が固定されておらず、共通の既定の列のリストに列を 1 つ追加するなどの変更が可能な場合、これはより効率的です。
では、どうすればそれができますか?
アイデアは、別のテーブルを作成し、そこに共通のデフォルト列を配置することです。このテーブルはダミー テーブルのようなものです。つまり、必要に応じて列を追加/削除できます。
例えば-
表-DefaultFields
列-item_title | item_description | item_thumbnail | item_keywords
DefaultFields
次に、次のようなループで動的にテーブルに値を挿入することもできます。
"INSERT INTO DefaultFields (item_table, item_title , item_description,item_thumbnail ,item_keywords) VALUES('"+ field.item_table + "','" + field.item_title + "','" + field.item_description+ "','" + field.item_thumbnail + "','" + field.item_keywords)");
注: field は、テーブルごとのループで値を保持するオブジェクトです。
DefaultFields
次に、テーブルを変更して、次のようなテーブルからこれらのデフォルト フィールドを作成できます。
"ALTER TABLE " + item_table+ " ADD COLUMN [" + field.item_title + "] Text"
これをテーブルごとに繰り返して、必要に応じて変更できます。
この設計パターンでは、次のことを行いたい場合でも:
1) 列をもう 1 つ追加するか、
2) 既存の列を削除するか、
3) 既存の列名を変更する
その後、ダミーテーブルでこれを行うことができ、残りは対応するテーブルの ALTER table コマンドによって更新されます。
私の意見では... いいえ、絶対にありません。
それには 2 つの理由があります。
データベースに論理的な意味を保持したい場合。今のところ、それがどのように構成されているかは明らかです。しかし、2 か月後 (または 1 年後) に、これほど明確になるでしょうか? 誰かがプロジェクトに参加する場合、アプリの別の論理ブロックが分離されている方が理解しやすいのではないでしょうか? というか……確かに人間も猫も動物です。それらの両方を同じボックス内に保管することはまだ論理的ですか?
パフォーマンス。テーブルが短いほど、リクエストは速くなります。データは、ディスク上で同じ容量を使用します。そして、あなたが探しているアイテムのタイプを知るための比較については話しません. つまり、アプリケーションのすべてのページを選択したい場合は、2 つの要求を比較するだけです。
複数のテーブル:
Select * from pages_tbl;
単一のテーブル:
Select * from item_tbl where type = 'page';
このデザインから何が得られますか? パフォーマンスも、ディスク容量も、読みやすさもありません。私は本当にそれの正当な理由がわかりません。