После авторизации Вы получите доступ к файлам, скрытым материалам сайта, исходным кодам
возможность комментировать и т.д.

Вы можете авторизоваться на сайте всего одним кликом:

2016-07-11
Основы Баз Данных → Отношение «многие ко многим»
Как правильно создавать/проектировать базы данных

Итак, у вас есть сайт с большой базой данных, количество материалов в которой неуклонно растет. Причем темпы роста настолько высоки, что вам уже трудно с ними справ­ляться...

Отношение «многие ко многим»

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

CREATE TABLE category (
   id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
   name VARCHAR(255)
) DEFAULT CHARACTER SET utf8 ENGINE=InnoDB

Теперь перед Вами стоит непростая задача: распределить все записи по категориям. И тут выясняется, что материалы о политике могут быть связаны с переходом через дорогу, а материалы, в которых упоминается д'Артаньян, — с адвокатами. Один и тот же материал попадает в несколько категорий, а каждая категория содержит множество материалов. Это и есть отношение «многие ко многим».

Большинство неопытных разработчиков начинает искать пути, позволяющие хранить нескольких значений в одном столбце. Им кажется, что к таблице material следует добавить поле category, а затем с его помощью выводить список идентификаторов тех категорий, в которые попадет каждый материал. Здесь пригодится еще один совет: если вам нужно сохранить несколько значений в одном поле, то ,скорее всего, вы допустили ошибку при проектировании.

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

Создадим таблицу materialcategory, пусть она связывает идентификаторы материалов materialid и категорий categoryid.

Промежуточная таблица создается аналогично любой другой. Отличие заключается в выборе первичного ключа. Во всех таблицах, с которыми вы до сих пор имели дело, был столбец id. При создании он обозначался как PRIMARY KEY (первичный ключ). В таких столбцах MySQL не позволяет хранить одинаковые значения, к тому же для них повышается скорость выполнения объединяющих запросов.

У промежуточной таблицы такого столбца с уникальными значениями нет. Каждый идентификатор материала может быть указан более одного раза. То же самое касается идентификаторов категорий — в одной категории может быть много материалов. Избегать следует повторяющихся пар. Кроме того, задача данной таблицы — упростить объединяющие запросы, поэтому прирост производительности, который обеспечивается первичным ключом, здесь не помешает. В связи с этим при создании первичного ключа для промежуточных таблиц указывается несколько столбцов.

CREATE TABLE materialcategory (
materialid INT NOT NULL,
categoryid INT NOT NULL,
PRIMARY KEY (materialid, categoryid)
) DEFAULT CHARACTER SET Utf8 ENGINE=InnoDB

Данный запрос создает таблицу, в которой первичный ключ формируют два столбца — materialid и categoryid. Это обеспечивает необходимую уникальность промежуточной таблицы, не дает присвоить материалу одну и ту же категорию более одного раза и повышает скорость объединяющих запросов, в которых данная таблица используется.

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

SELECT materialtext
FROM joke INNER JOIN materialcategory
   ON joke.id = materialid
INNER JOIN category
   ON categoryid = category.id
WHERE name = "CategoryName"

Как видите, в этом запросе используются два оператора JOIN. Первый объединяет таблицы material и materialcategory, а второй берет готовые данные и объединяет их с таблицей category. По мере того как структура вашей базы данных будет усложняться, подобные запросы с несколькими объединениями станут нормой.

1394
0
Пожалуйста, авторизируйтесь, чтобы скачать архив с файлами урока