Дизайн базы данных, моя база данных рациональна правильно один первичный ключ для нескольких внешних ключей?

У меня есть идея, которую я хочу выполнить, и я очень сильно разбираюсь в дизайне своей базы данных, когда дело доходит до отношений между таблицами. Я хочу иметь возможность ввести 3 ингредиента в 3 <input type="text"> поля и искать все рецепты с этими ингредиентами.

у меня есть 3 стола...

  • ингредиенты
  • рецепт
  • меню

столбцы, которые выделены жирным шрифтом, являются моими первичными ключами, и я хочу, чтобы столбцы, выделенные курсивом, были внешними ключами.

Пример - iName является первичным ключом для iName1 iName2 и iName3.


ИНГРЕДИЕНТЫ

iName - iType

РЕЦЕПТ

mName - iName1 - iName2 - iName3 - метод

МЕНЮ

mName - mDiscription - MAllergy


Мои вопросы... достаточно ли эффективны отношения между моими таблицами для того, что я хочу сделать? и что будет запрос на присоединение, если я хочу, например,

SELECT mName, mDiscripton, mAllergy
FROM menu
WHERE iName1 = input etc etc

Любой пролить свет на эту тему будет очень полезно, у меня уже есть версия базы данных с одной таблицей, и запрос, который я использую, работает нормально, я просто хочу изменить дизайн базы данных и изменить свой запрос в соответствии с требованиями.

2 ответа

Ваш дизайн не хватает одной таблицы, чтобы быть эффективным; удалите iName1 to iName3 из таблицы рецептов и добавьте таблицу сопоставления "recipe_ingredients" с внешними ключами для рецепта и одним ингредиентом. Затем у вас будет от одной до нескольких строк в этой таблице для каждого рецепта (посмотрите на мой пример). Но: Вы можете легко найти все рецепты, где используется ингредиент. И вы можете использовать 10000 ингредиентов для одного рецепта при необходимости.

Как меню столов связано с рецептами? Меню всегда состоит из одного рецепта? В противном случае также добавьте таблицу сопоставления для этого отношения.

SELECT mName, mDiscription, mAllergy 
    FROM menu
        JOIN recipe ON recipe.mName = menu.mName
        JOIN recipe_ingredients ON recipe_ingredients.mName = recipe.mName
    WHERE recipe_ingredients.iName = 'whatever'

Пожалуйста, не используйте столбцы 1..n, чтобы сохранить соединение n..m между двумя таблицами.

Поскольку вы можете использовать один ингредиент в разных рецептах, вам потребуется таблица соответствия. Они часто называются table1_2_table2, или в вашем случае recipe2ingredient. Там вы храните первичные ключи из обеих таблиц (в большинстве случаев как объединенный первичный ключ в этой таблице, что часто имеет смысл)

То же самое должно пойти на меню и рецепт, так как вы можете использовать рецепт в нескольких меню.

Так

Table 1 - Menu    (ID, Name, ... whatever columns you need on top of that)
Table 2 - Recipe (ID, Name, ...whatever columns you could desire)
Table 3 - Menu2Recipe( IdMenu, IdRecipe)
Table 4 - Ingredient (ID, Name, measurement unit)
Table 5 - Ingredient2Recipe( IdRecipe, IdIngredient, Amount )

Надеюсь, вам это понятно.

Другие вопросы по тегам