Дизайн базы данных, моя база данных рациональна правильно один первичный ключ для нескольких внешних ключей?
У меня есть идея, которую я хочу выполнить, и я очень сильно разбираюсь в дизайне своей базы данных, когда дело доходит до отношений между таблицами. Я хочу иметь возможность ввести 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 )
Надеюсь, вам это понятно.