Получить все много: много отношений из ссылки / таблицы соединений - PullRequest
1 голос
/ 06 мая 2020

У меня возникли трудности с запросом возможных отношений в сценарии «Многие: многие».

Я представляю свою схему:

schema

Что я делаю знает, как запросить с помощью этой схемы:

  • Все диапазоны, к которым принадлежит данный пользователь.
  • Все пользователи, которые принадлежат данному диапазону.

То, что я пытаюсь сделать, это:

  • Получить все члены группы по все диапазоны, которые данный Пользователь принадлежит.
  • ie, скажем, я участвую в 5 группах, я хочу знать, кто все мои товарищи по группе.

Мои первые вопросы: :

  • Есть ли название для этого типа запроса? Где меня больше интересуют соединенные отношения, чем к чему я присоединен (просто говоря, это заставило меня захотеть поместить всю эту систему в базу данных Graph: /)? Я хотел бы выучить правильную терминологию, чтобы помочь мне найти в Google проблемы в будущем.
  • Это ужасная идея в мире РСУБД в целом? Я чувствую, что это должно быть обычным вариантом использования, но я хочу знать, ошибаюсь ли я полностью.

Подведем итог:

  • Я хочу запросить приведенная выше схема с ожидаемым выходом, представляющим одну строку для каждого пользователя в качестве участников группы, с которыми данный пользователь совместно использует полосу.

1 Ответ

0 голосов
/ 06 мая 2020

Терминология

Ваша терминология кажется правильной - «многие ко многим», часто записываемые как «многие: многие» с двоеточием. Иногда средняя таблица (band_members) называется «таблицей мостов».

Вероятно, вы можете отбросить band_members.id, поскольку два внешних ключа также составляют составной первичный ключ (и первичный ключ фактически может быть определен таким образом, поскольку обычно пользователь не может быть членом одного и того же диапазона дважды. Единственное исключение из этого - если пользователь может иметь более одной роли в одном и том же диапазоне).

Решение

На первый взгляд это звучит просто - мы можем видеть взаимосвязи таблиц, и обычно между ними просто используется INNER JOIN. Есть три таблицы, так что это будет два объединения.

Однако сначала мы должны правильно концептуализировать проблему. Проблема заключается в том, что соединение между пользователями и участниками группы (идентификатор пользователя) на самом деле должно использоваться для двух вещей:

  • какой пользователь в какой группе
  • фильтрация по пользователю

Итак, для этого нам нужно ввести одну таблицу с несколькими целями:

SELECT
    Users.first_name, Users.last_name
FROM Users
INNER JOIN Band_Members Band_Members1 ON (Band_Members1.user_id = Users.Id)
INNER JOIN Band_Members Band_Members2 ON (Band_Members1.band_id = Band_Members2.band_id)
WHERE
    Band_Members2.user_id = 1

Здесь вы можете видеть, что я присоединился к Band_Members дважды, и когда это произойдет , нужно называть их по-разному, чтобы на них можно было ссылаться отдельно. Первый экземпляр выполняет очевидное соединение между таблицей Users и таблицей моста, а второй устанавливает связь между «Users, которые находятся в Bands» и «Bands, в которых я нахожусь».

Конечно, это Решение требует, чтобы вы знали свой идентификатор пользователя. Если бы вы хотели выполнить аналогичный запрос, но с фильтром на основе вашего имени, тогда вам пришлось бы присоединиться к другой (с измененным псевдонимом) копии таблицы User, чтобы вы могли различать две разные цели: «Пользователи, которые являются в бэндах "и" ваш Пользователь ".

...