Пример связи «многие-ко-многим»
Здравствуйте! Не могу понять связь «многие ко многим». Что она значит? Приведите, пожалуйста, пример, когда эту связь нужно устанавливать. Лучше даже пример из жизни приведите, пожалуйста, когда такая связь осуществляется.
Отслеживать
задан 11 янв 2012 в 12:45
elenavictory elenavictory
320 3 3 золотых знака 7 7 серебряных знаков 23 23 бронзовых знака
3 ответа 3
Сортировка: Сброс на вариант по умолчанию
«Один-ко-многим» — тип связи таблиц, когда одной записи главной таблицы можно сопоставить несколько записей подчинённой таблицы. Это наиболее частый вид связи между таблицами. Ну, например, если создавать телефонный справочник, то необходимо учесть, что у одного человека может быть несколько телефонов (2 мобильных, 1 домашний и 1 служебный). Или ещё пример: студент (записи о студентах хранятся в главной таблице) обучается в ВУЗе — он изучает несколько предметов (записи о предметах хранятся в подчинённой таблице), по которым сдаёт экзамены и зачёты.
А связь «многие-ко-многим» возникает в тех случаях, когда одной записи одной таблицы может соответствовать несколько записей другой таблицы и наоборот: когда одной записи второй таблицы может соответствовать несколько записей первой таблицы. От такого типа связи следует избавляться и приводить к виду «один-ко-многим». Пример такого вида связи: имеем 2 таблицы «Товары» и «Клиенты», каждый клиент может приобрести несколько товаров, в свою очередь каждый товар (по наименованию) может быть приобретён (или заказан) несколькими клиентами. Ещё пример (по ВУЗ): пусть есть 2 таблицы «Преподаватель» и «Студент», каждый преподаватель может обучать нескольких студентов, в то же время каждый студент может обучаться у нескольких преподавателей.
Отслеживать
ответ дан 11 янв 2012 в 12:54
DelphiM0ZG DelphiM0ZG
3,045 15 15 серебряных знаков 18 18 бронзовых знаков
А, например, в Access как устанавливается подобная связь в схеме данных?
10 ноя 2016 в 4:03
Почему «От такого типа связи следует избавляться»? Связь как связь.
1 дек 2016 в 8:40
Примеры, приведённые для связи «многие-ко-многим» хоть и верные по сути, ошибочны с точки зрения проектирования бд:) например, в примере про студентов — каждый студент состоит в группе, а преподаватель преподаёт предмет. У группы есть предметы, обратной связи никакой:) ну то есть по логике связи «многие ко многим» тут неоткуда взяться.
Пример связи многие-ко-многим (PostgreSQL)
Связь многие-ко-многим – это связь, при которой множественным записям из таблицы (A), могут соответствовать множественные записи из таблицы (B).
Пример такой связи, люди и их счета в банках.
Например, есть таблица людей (person) и есть таблица с банками (bank). У человека может быть счет в одном банке, или нескольких, а может вообще не быть, как на ER-диаграмме, указанной на рисунке ниже.
Таблицы person, bank, person_bank
Связь многие-ко-многим, между таблицами person и bank осуществляется при помощи третьей таблицы person_bank, у которой 2 внешних ключа на таблицы person и bank соответственно. Чтобы связь пользователь-банк не повторялась дважды, на поля person_id и bank_id создается уникальное ограничение или проще ключ.
CREATE TABLE person ( id SERIAL PRIMARY KEY, full_name VARCHAR ); CREATE TABLE bank ( id SERIAL PRIMARY KEY, name VARCHAR ); CREATE TABLE person_bank ( id BIGSERIAL PRIMARY KEY, person_id INTEGER NOT NULL REFERENCES person, bank_id INTEGER NOT NULL REFERENCES bank, UNIQUE (person_id, bank_id) );
Данные
Люди и их связь с банками.
INSERT INTO bank (id, name) VALUES (1, ‘Сбер’), (2, ‘Тинькофф’), (3, ‘Райффайзен’), (4, ‘ВТБ’); INSERT INTO person (id, full_name) VALUES (1, ‘Иванов Сидор Петрович’), (2, ‘Сидоров Петр Иванович’), (3, ‘Петров Иван Сидорович’), (4, ‘Наличный Артем Андреевич’); INSERT INTO person_bank (person_id, bank_id) VALUES (1, 1), (1, 3), (2, 2), (2, 3), (2, 4), (3, 1), (3, 4);
Связь многие-ко-многим
Выберем всех людей и их банки.
SELECT p.full_name AS person_full_name, b.name AS bank_name FROM person p LEFT JOIN person_bank pb ON pb.person_id = p.id LEFT JOIN bank b ON b.id = pb.bank_id;
В результате будут возвращены следующие данные:
person_full_name | bank_name |
Иванов Сидор Петрович | Сбер |
Иванов Сидор Петрович | Райффайзен |
Сидоров Петр Иванович | Тинькофф |
Сидоров Петр Иванович | Райффайзен |
Сидоров Петр Иванович | ВТБ |
Петров Иван Сидорович | Сбер |
Петров Иван Сидорович | ВТБ |
Наличный Артем Андреевич |
Как видно в таблице выше, у Иванова и Петрова по 2 банка, у Сидорова 3 у Наличного нет связи с банками вообще.
✖ ❤ Мне помогла статья нет оценок
11094 просмотра 6 комментариев Артём Фёдоров 22 января 2022
Категории
Читайте также
- Заполнение данных при помощи транзакций (PostgreSQL)
- Select like and char_length (MySQL)
- Cкопировать таблицу с данными (MySQL)
- INSERT SELECT (MySQL)
- Добавить запись в таблицу (MySQL)
- GROUP_CONCAT (MySQL)
- GROUP_CONCAT DISTINCT (MySQL)
- Очистить таблицу (MySQL)
- Вычесть один день от даты (PostgreSQL)
- Скопировать структуру таблицы (MySQL)
- Переименовать таблицу (MySQL)
- Как узнать количество записей в дочерней таблице (MySQL)
Комментарии
Комментарий помечен как спам и скрыт. Показать
Максим 23 марта 2023 в 15:25
Добрый день! Заинтересовал ваш проект. Если рассматриваете продажу, готов предложить за него 85000 рублей по предварительной оценке. Жду ответ.
Комментарий помечен как спам и скрыт. Показать
Максим 23 марта 2023 в 15:25
Добрый день! Заинтересовал ваш проект. Если рассматриваете продажу, готов предложить за него 85000 рублей по предварительной оценке. Жду ответ.
Комментарий помечен как спам и скрыт. Показать
Дмитрий 27 февраля 2023 в 23:44
Меня зовут Дмитрий (Инстаграм: kupratsevich_dima). Я ищу хорошие сайты для покупки и дальнейшего развития.
Понравился ваш проект expange.ru. Прямо сейчас рассматриваю его к приобретению.
Предварительно предлагаю 53000 рублей. Цена может быть пересмотрена в большую сторону.
Если вам это интересно, то можем обсудить.
Почта: kuprdimasites@gmail.com
Телефон (whatsapp): +79959176538
Telegram: kupratsevich
Комментарий помечен как спам и скрыт. Показать
Дмитрий 27 февраля 2023 в 23:42
Меня зовут Дмитрий (Инстаграм: kupratsevich_dima). Я ищу хорошие сайты для покупки и дальнейшего развития.
Понравился ваш проект expange.ru. Прямо сейчас рассматриваю его к приобретению.
Предварительно предлагаю 53000 рублей. Цена может быть пересмотрена в большую сторону.
Если вам это интересно, то можем обсудить.
Почта: kuprdimasites@gmail.com
Телефон (whatsapp): +79959176538
Telegram: kupratsevich
Комментарий помечен как спам и скрыт. Показать
07 октября 2022 в 19:49
Мы ищем хорошие сайты для покупки и дальнейшего развития.
Понравился ваш проект expange.ru. Прямо сейчас рассматриваю его к приобретению.
Готов купить его за 15 месяцев окупаемости (доход в месяц * 15). Цена может быть пересмотрена в большую сторону.
Если вам это интересно, то можем обсудить по почте kuprdimasites@gmail.com, телефону +79959176538 (whatsapp) или Telegram (kupratsevich).
Как реализовать связь многие ко многим
Данное руководство устарело. Актуальное руководство: Руководство по Entity Framework Core
Последнее обновление: 31.10.2015
Еще одним способом ассоциации объектов является связь многие-ко-многим. Например, у нас есть модель футболистов и есть модель команд. На протяжении всей жизни футболист может поиграть в различных командах, а в одной команде может поиграть множество разных футболистов. На уровне моделей это выглядит так:
public class Team < public int Id < get; set; >public string Name < get; set; >public ICollection Players < get; set; >public Team() < Players = new List(); > > public class Player < public int Id < get; set; >public string Name < get; set; >public string Position < get; set; >public int Age < get; set; >public ICollection Teams < get; set; >public Player() < Teams = new List(); > >
Обе модели имеют свойства-коллекции, через которые и будет осуществляться связь многие-ко-многим. В итоге, если мы используем CodeFirst, то автоматически будет создаваться база данных со следующей схемой:
То есть создается промежуточная таблица, которая хранит наборы пар Player-Team. И если бы мы использовали подход Database First, то нам надо было также создать эту таблицу.
Используем модели. Добавление и вывод:
using(SoccerContext db = new SoccerContext()) < // создание и добавление моделей Player pl1 = new Player < Name = "Роналду", Age = 31, Position = "Нападающий" >; Player pl2 = new Player < Name = "Месси", Age = 28, Position = "Нападающий" >; Player pl3 = new Player < Name = "Хави", Age = 34, Position = "Полузащитник" >; db.Players.AddRange(new List < pl1, pl2, pl3 >); db.SaveChanges(); Team t1 = new Team < Name = "Барселона" >; t1.Players.Add(pl2); t1.Players.Add(pl3); Team t2 = new Team < Name = "Реал Мадрид" >; t2.Players.Add(pl1); db.Teams.Add(t1); db.Teams.Add(t2); db.SaveChanges(); foreach(Team t in db.Teams.Include(t=>t.Players)) < Console.WriteLine("Команда: ", t.Name); foreach(Player pl in t.Players) < Console.WriteLine("- ", pl.Name, pl.Position); > Console.WriteLine(); > >
При добавление одной модели в список к другой важно помнить, что это список уже должен быть создан, иначе будет выброшено исключение. В данном случае мы создаем список в конструкторе обоих моделей. Также допустимо создание списка непосредственно в программе.
// удаляем связи с одним объектом Player pl_edit = db.Players.First(p=>p.Name=="Месси"); Team t_edit = pl_edit.Teams.First(p=>p.Name=="Барселона"); t_edit.Players.Remove(pl_edit);
Удаление игрока из списка команды будет означать удаление строки из таблицы TeamPlayers, в которой id игрока сопоставляется id команды.
Удаление же игрока или команды вообще из базы данных приводит к тому, что все строки в таблице TeamPlayers, которые содержат id удаленного объекта, также будут удалены:
Player pl_delete = db.Players.First(p=>p.Name=="Месси"); db.Players.Remove(pl_delete);
Создание связей типа «многие-ко-многим»
Связи типа «многие-ко-многим» используются между таблицами чаще всего. С их помощью можно узнавать важные сведения, например, с какими клиентами связывались ваши менеджеры по продажам и какие продукты входили в заказы.
Связь «многие-ко-многим» предполагает возможность связи одного или нескольких элементов из одной таблицы с одним или несколькими элементами из другой таблицы. Примеры:
- В таблице «Заказы» указаны заказы, сделанные разными клиентами из таблицы «Клиенты». Каждый клиент мог сделать несколько заказов.
- В таблице «Продукты» указаны продаваемые товары, каждый из которых может фигурировать в нескольких заказах из таблицы «Заказы».
- Каждый продукт может входить в один заказ как в одном, так и в нескольких экземплярах.
Например, в заказ Арины Ивановой № 1012 могут входить продукты № 12 и 15, а также пять продуктов № 30.
Создание связи «многие-ко-многим»
Связи «многие-многим» создаются не так, как «один-к-одному» или «один-к-многим». Для таких связей достаточно соединить соответствующие поля линией. Чтобы создать связи «многие-к-многим», необходимо создать таблицу для соединения двух других. Эта новая таблица называется промежуточной (или иногда связующим или связующим).
В рассмотренном ранее примере создавалась таблица «Сведения о заказах» с записями, в которых для каждого товара в нужном порядке указывались номер заказа из таблицы «Заказы» и код продукта из таблицы «Продукты». Первичный ключ для этой таблицы создавался путем объединения ключей из двух других таблиц.
Ниже рассмотрим пример, когда в заказ Арины Ивановой № 1012 входят продукты № 12, 15 и 30. Это значит, что записи в таблице «Сведения о заказах» выглядят следующим образом:
Арина заказала по одному продукту № 12 и 15, а также пять продуктов № 30. Создать другие строки с номером заказа 1012 и кодом продукта 30 нельзя, потому что поля «Номер заказа» и «Код продукта» вместе составляют первичный ключ, а первичные ключи должны быть уникальными. Вместо этого можно добавить в таблицу «Сведения о заказах» поле «Количество».
Создание промежуточной таблицы
- Выберите Создание >Таблица.
- Выберите Сохранить.
- Укажите описательное имя таблицы. Чтобы подчеркнуть назначение таблицы, можете включить в ее имя слова связующая или промежуточная.
Создание полей в промежуточной таблице
Столбец «Код» автоматически добавляется в Access в качестве первого. Измените имя этого поля на идентификатор вашей первой таблицы в связи «многие-ко-многим». Например, если первая таблица называется «Заказы», поле «Код» в ней переименовано в «Номер заказа», и его первичный ключ — число, измените имя поля «Код» в новой таблице на «Номер заказа», а в качестве типа данных выберите Числовой.
- В режиме таблицы выберите заголовок столбца Код и введите новое имя поля.
- Выберите переименованное поле.
- На вкладке Поля в списке Тип данных выберите тип, как в соответствующем поле исходной таблицы, например Числовой или Короткий текст.
- Щелкните надпись Щелкните для добавления и выберите тип данных, соответствующий первичному ключу во второй таблице. В заголовке столбца введите имя поля первичного ключа из второй таблицы, например «Код продукта».
- Если вам требуется отслеживать другую информацию об этих записях, например количество товаров, создайте дополнительные поля.
Объединение полей для создания первичного ключа
Теперь, когда у вас есть поля с идентификаторами двух таблиц, между которыми вы хотите создать связь, в промежуточной таблице следует создать первичный ключ на основе этих идентификаторов.
- Откройте промежуточную таблицу в режиме конструктора.
- Выберите обе строки с идентификаторами. (Если вы следовали предыдущим указаниям, это будут две первые строки.)
- На вкладке Конструктор нажмите кнопку Ключевое поле.
Рядом с обоими полями будут отображаться значки ключей.
Соединение трех таблиц для создания связи «многие-ко-многим»
Чтобы завершить создание связи «многие-ко-многим», создайте связь «один-ко-многим» между полем первичного ключа в каждой таблице и соответствующим полем в промежуточной таблице. Инструкции см. в статье Начало работы со связями между таблицами.
После этого связи должны выглядеть следующим образом: