2

キッチン/レシピ管理用のプログラムを書いています。現在、プログラムは新しい成分をデータベースに追加できます。次のステップは、材料を使用してデータベースに新しいレシピを追加することです。

各レシピには複数の材料があり、無制限にレシピに追加できるため、選択した材料ごとに個別の列を作成するのは効率的ではありません (私は推測しています)。

したがって、材料の選択を保存するために私が思いついた方法は次のとおりです。

  1. データベースのレシピ テーブルにレシピ_成分列を追加し、各成分の名前を 1 つの (テキスト) フィールドにカンマで区切って格納します (CSV スタイル)。

  2. PHP スクリプトを作成して、recipe_ingredients のリストを配列に格納します。

  3. 他のすべての属性 (recipe_ingredients_serving_size、recipe_ingredients_calories など) についても同じことを行います。

問題は、この方法が最適かどうか、そうでない場合、これを行うためのより良い方法は何かということです。

4

2 に答える 2

2

これは、この問題を解決するための理想的なアプローチではありません。

列内の値をコンマで区切ると、これらの値はほとんど役に立たなくなります。多くの材料を 1 つの文字列に連結するだけでは、材料ごとにレシピをクエリするのは面倒です。

また、コンマ区切りの文字列として保存している場合、単一の食材のカロリー数を食材にどのように関連付けますか?

理想的な解決策は、食材用の新しいテーブルを作成し、そのテーブルに名前と関連情報を保存することです..例

ingredients
-----------
id 
name
num_calories

多くの食材を使ったレシピはたくさんあるので、食材を特定のレシピにリンクするテーブルを作成します。これにより、食材とレシピの関係が多対多ではなく、多対 1 対多になります。

レシピ_材料
------------------
レシピID
成分ID

ここで正規化について読む必要があります。

于 2012-07-15T00:35:19.490 に答える
2

これは単純な N:M (多対多) の関係であり、あなたが提示したアプローチは、効率と管理の面で最悪の結果をもたらす可能性があります。


これがあなたの状況です:

  • と の 2 つのエンティティがrecipesありingredientsます。
  • 1 つの材料が多くのレシピの一部になる場合があります。
  • 1 つのレシピが多くの材料で構成されている場合があります。

任意の 2 つのエンティティ間にこの関係がある場合は常に、2 つではなく 3 つのテーブルが必要になります。

+-----------+     +-------------------------+     +-------------------+
| recipes   |     | recipes_has_ingredients |     | ingredients       |
+-----------+     +-------------------------+     +-------------------+
| recipe_id |     | recipe_id               |     | ingredient_id     |
| name      |     | ingredient_id           |     | name              |
| ...       |     +-------------------------+     | calories          |
+-----------+                                     +-------------------+

recipesおよびベース テーブルingredientsと呼ばれるもので、特定のエンティティに関する固有の情報が格納されます。

このrecipes_has_ingredientsテーブルは相互参照テーブル(または "XREF") と呼ばれるもので、2 つのエンティティ間の関連付けが格納されます。このテーブルのフィールド:recipe_idおよびingredient_id両方ともそれぞれのベース テーブルにリンクしており、XREF テーブルの各行の 2 つの組み合わせは一意です。基本的に、それぞれrecipe_idが持つ可能性のある多くの関連付けを異なるにマップし、ingredient_idその逆も同様です。

この設計が多対多の関係を促進するのはなぜですか? その XREF テーブルのデータは次のように表示されるためです。

+-----------------------------+
| recipe_id  |  ingredient_id |
+-----------------------------+
| 1          |  1             |
| 1          |  2             |
| 1          |  3             |
| 2          |  1             |
| 2          |  2             |
| 2          |  3             |
| 3          |  1             |
| 3          |  2             |
| 3          |  3             |
+-----------------------------+

明らかなように、1 つのレシピが多くの (3) の材料に関連付けられており、1 つの材料が多くの (3) のレシピに関連付けられています。また、いずれかの列の値を繰り返すことができるが、2 つの列の組み合わせは一意であることに注意してください。これは、N:M 関係を機能させるこの設計の重要な側面です。

したがって、この設計を使用してデータを簡単に取得および管理する方法の簡単な例を次に示します。

// Given a particular recipe_id, retrieve all ingredients used in that recipe:   

SELECT     name
FROM       recipes_has_ingredients
INNER JOIN ingredients USING (ingredient_id)
WHERE      recipe_id = <id>

// Retrieve the name of recipe (of id 4), and total amount of calories it has:

SELECT      a.name, 
            SUM(c.calories) AS calorie_count
FROM        recipes a
INNER JOIN  recipes_has_ingredients b ON a.recipe_id = b.recipe_id
INNER JOIN  ingredients c ON b.ingredient_id = c.ingredient_id
WHERE       a.recipe_id = 4
GROUP BY    a.recipe_id, 
            a.name

// Given a list of ingredient_id's, retrieve all recipes that contain 
// ALL of the listed ingredients

SELECT     name
FROM       recipes
INNER JOIN recipes_has_ingredients USING (recipe_id)
WHERE      ingredient_id IN (1,2,3)
GROUP BY   recipe_id
HAVING     COUNT(*) = 3

// Given a particular recipe_id (id 6), add two more ingredients 
// that it has (ids 4 & 9):

INSERT INTO recipes_has_ingredients VALUES (6,4), (6,9);

// Delete a particular recipe:

DELETE FROM recipe WHERE recipe_id = 4

^ リレーションシップ間の CASCADE ルールを適切に定義した場合、上記のDELETE操作により、そのレシピのアソシエーションもすべて削除されます。


元のデザインを振り返って、レシピに含まれる特定の食材を更新または削除したい場合や、食材の名前を変更したい場合はどうしますか? csv 文字列の正しい位置を変更するにはハックな手続き型コードが必要になるか、テーブルのすべての行を更新して単一の成分のわずかな変更を反映する必要があります。

次のような、オリジナルのデザインを使用しなければ答えられなかった多くの説得力のある質問もあります。

  • カロリー数が最高/最低のレシピは?
  • 最も多くのレシピに含まれる食材は?

...リストは続きますが、この設計を実装する利点は十分に役立ちます。物事を正しく行うことで、多くの困難や苦しみから身を守ることができます。=)

于 2012-07-15T00:50:11.383 に答える