MySQL - Реляционные / промежуточные таблицы и запросы JOIN? - PullRequest
0 голосов
/ 06 мая 2020

Прочитал это (целую вечность!) И не могу получить четкую картину.

Во-первых, если у меня есть две таблицы (например, рецепты и ингредиенты) с отношением «многие ко многим», и я создать промежуточную / реляционную таблицу, как мне написать запрос SQL, чтобы найти все рецепты, например, с бананами в них?

Во-вторых, зачем мне эта третья реляционная таблица, если я могу найти та же информация с использованием запросов JOIN без создания третьей таблицы ??

Очень признательны за ясное, полезное объяснение, спасибо.

1 Ответ

1 голос
/ 06 мая 2020

как мне написать запрос SQL, чтобы найти все рецепты, например, с бананами в них?

Вы можете сделать:

select distinct r.id, r.name
from recipe r
join recipe_ingredient ri on ri.id_recipe = r.id
join ingredient i on i.id = ri.id_ingredient
where i.name = 'banana'

Во-вторых, зачем мне эта третья реляционная таблица, если я могу найти ту же информацию с помощью запросов JOIN без создания третьей таблицы?

Поскольку рецепт может иметь много ингредиенты, и ингредиент может быть связан с многими рецептами, отношения между этими двумя таблицами не 1: n, а n: m. Следовательно, вам нужна промежуточная таблица, как показано ниже:

create table recipe (
  id int primary key not null,
  name varchar(20)
);

create table ingredient (
  id int primary key not null,
  name varchar(20)
);

create table recipe_ingredient (
  id int primary key not null,
  id_recipe int not null,
  id_ingredient int not null,
  quantity double not null,
  foreign key fk1 (id_recipe) references recipe (id),
  foreign key fk2 (id_ingredient) references ingredient (id)
);

Если ингредиент всегда присутствует в одном рецепте, структура будет проще, как вы, кажется, думаете. Эта более простая структура, вероятно, будет выглядеть так:

create table recipe (
  id int primary key not null,
  name varchar(20)
);

create table ingredient (
  id int primary key not null,
  name varchar(20),
  id_recipe int not null,
  foreign key fk3 (id_recipe) references recipe (id) 
);

Такая модель в данном случае нецелесообразна. В конечном итоге у вас будет один и тот же ингредиент несколько раз. Например, если в пироге используется «мука», а в хлебе используется «мука», то «мука» дважды попадет в таблицу ингредиентов. Не лучшая идея.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...