リレーショナルデータベースモデルについては、曲げられないルールがいくつかあります(そして、良かったのはほんのわずかです)。そのうちの一つは、何を保存すればいいのかわからないと、保存するのに苦労するということです。たぶん、それを取得するのはさらに難しいでしょう。
とは言うものの、ビジネスルールの現実は、データベース設計の象牙の塔ほど明確ではないことがよくあります。最も重要なことは、スキーマを変更せずに新しいプロパティを導入する方法が必要な場合もあれば、必要な場合もあります。
これを実現するための2つの実行可能な方法は次のとおりです。
- 緩いスキーマまたは存在しないスキーマ(NoSQLおよびその仲間)に特化したデータストアを使用します。これを詳細に説明することはCS論文の主題であり、スタックオーバーフローの答えではありません。
- 私の推奨事項:別のプロパティテーブルを使用してください-これは次のようになります:
議論のために、あなたの製品は常に(一意の文字列)、name
(整数)id
、、、そして時々(整数)と(文字列)を持っていると仮定して、これらの表を検討してくださいbrightness
contrast
chromaticity
foo
bar
CREATE TABLE products (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
brightness INT,
contrast INT,
chromaticity INT,
UNIQUE INDEX(name)
);
CREATE TABLE properties (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
proptype ENUM('null','int','string') NOT NULL default 'null',
UNIQUE INDEX(name)
);
INSERT INTO properties VALUES
(0,'foo','int'),
(0,'bar','string');
CREATE TABLE product_properties (
id INT PRIMARY KEY AUTO_INCREMENT,
products_id INT NOT NULL,
properties_id INT NOT NULL,
intvalue INT NOT NULL,
stringvalue VARCHAR(250) NOT NULL,
UNIQUE INDEX(products_id,properties_id)
);
これで、「標準」プロパティは通常どおりテーブルに表示され、「オプション」プロパティは、またはの値で製品IDとプロパティIDを参照products
するの行に格納されます。product_properties
intvalue
stringvalue
それらを含む製品を選択すると、次のfoo
ようになります
SELECT
products.*,
product_properties.intvalue AS foo
FROM products
LEFT JOIN product_properties
ON products.id=product_properties.product_id
AND product_properties.property_id=1
あるいは
SELECT
products.*,
product_properties.intvalue AS foo
FROM products
LEFT JOIN product_properties
ON products.id=product_properties.product_id
LEFT JOIN properties
ON product_properties.property_id=properties.id
WHERE properties.name='foo' OR properties.name IS NULL
これにはパフォーマンスのペナルティが発生することを理解してください。実際、パフォーマンスと柔軟性をトレードオフします。別のプロパティを追加INSERT
することは、行を追加するだけでproperties
あり、スキーマは同じままです。