"Информатика", Поляков К.Ю., Еремин Е.А.
Многотабличная база данных хранит сведения в нескольких таблицах, каждая из которых описывает свой объект: например, учеников и классы. Такое разделение помогает не повторять одни и те же данные и уменьшает риск ошибок при их изменении. Чтобы находить нужные записи и связывать таблицы, используют ключи. Первичный ключ отличает запись от остальных, а внешний указывает на запись в другой таблице. Разберём, как устроены связи «один к одному», «один ко многим» и «многие ко многим».
Текст подготовлен нейронной сетью по теме параграфа и не заменяет учебник — важные факты и формулировки сверяйте с ним.
Многотабличная база данных — это база, в которой сведения хранятся в нескольких связанных таблицах. Таблицы разделяют по смыслу: например, сведения об учениках записывают отдельно от сведений о классах. Так проще находить и обновлять данные, не дублируя их без необходимости.
Первичный ключ — поле или набор полей, однозначно определяющих запись в таблице. Значения такого ключа не должны повторяться, иначе по нему нельзя будет понять, какую именно запись нужно найти или изменить. Например, каждому классу можно присвоить отдельный код.
Внешний ключ — поле таблицы, содержащее значение первичного ключа другой таблицы. Оно указывает, с какой записью связана текущая запись: например, код класса в записи об ученике отсылает к нужному классу. Благодаря этому сведения не приходится копировать целиком.
Связь таблиц — соответствие между записями разных таблиц, которое устанавливают по значениям ключевых полей. Если значение внешнего ключа совпало со значением первичного ключа, записи относятся друг к другу. Связи помогают собирать сведения из разных частей базы.
Если поместить все сведения в одну таблицу, общие данные придётся повторять в каждой строке. Например, название класса будет указано рядом с каждым учеником этого класса. Если название изменится, его нужно исправить во многих местах, а пропуск или ошибка в одной строке создаст несогласованность. Разделение таблиц позволяет хранить название класса один раз и ссылаться на него.
Каждую сущность — объект определённого вида, о котором хранят данные, — помещают в отдельную таблицу. Ученики и классы являются разными сущностями, поэтому для них создают разные таблицы. Первичный ключ помогает различать записи внутри каждой таблицы даже тогда, когда другие значения совпадают. Например, у двух учеников могут быть одинаковые фамилии, но разные номера.
Связь задают внешним ключом: его значение должно указывать на подходящую запись в другой таблице. Допустим, в таблице «Ученики» хранится код класса, а в таблице «Классы» этот код является первичным ключом. По совпадающим значениям можно определить, к какому классу относится ученик. Внешний ключ не заменяет запись класса, а только ссылается на неё.
При связи «один ко многим» одной записи первой таблицы соответствуют несколько записей второй. Один класс может включать многих учеников, но каждый ученик обычно относится к одному классу. Поэтому внешний ключ класса помещают в таблицу «Ученики»: каждый ученик получает ссылку на свой класс. Если поместить несколько ученических записей в одну ячейку таблицы классов, поиск и обработка станут сложнее.
Чтобы получить общие сведения, например фамилию ученика и название его класса, записи выбирают по совпадающим значениям ключей. Это называется соединением таблиц в запросе: база находит соответствующие строки, не требуя вручную переписывать их в одну таблицу. Такой способ сохраняет данные разделёнными, но позволяет использовать их вместе. Для связи «многие ко многим», например книг и авторов, создают дополнительную таблицу, где каждая строка соединяет одну книгу с одним автором.
В таблице сопоставлены ключи и виды связей: по ней можно проверить, где хранить ссылку и как представить разные соответствия между записями. Примеры показывают типичные случаи, а не единственно возможные названия полей. При проектировании базы ориентируйся на смысл данных и правила предметной области.
| Элемент | Где находится | Назначение | Пример |
|---|---|---|---|
| Первичный ключ | В своей таблице | Однозначно определяет запись | Код класса в таблице «Классы» |
| Внешний ключ | В таблице, которая ссылается на другую | Указывает на запись по её первичному ключу | Код класса в таблице «Ученики» |
| Связь «один к одному» | Между двумя таблицами | Одной записи соответствует одна запись | Человек и его паспортные данные |
| Связь «один ко многим» | Внешний ключ обычно на стороне «многие» | Одна запись связана с несколькими | Класс и ученики |
| Связь «многие ко многим» | Через дополнительную таблицу | Каждая сторона может иметь несколько связей | Книги и авторы |
Условие: нужно выбрать поле, которое однозначно обозначает каждый класс. Название класса может показаться удобным: оно понятно человеку. Проверим, подходит ли оно как ключ, и подберём надёжный вариант.
Ответ: лучше использовать уникальный код класса как первичный ключ. Название можно оставить отдельным полем, предназначенным для отображения. Так запись не потеряет свою идентичность, если название потребуется изменить.
Условие: таблицы «Ученики» и «Классы» должны показывать, в каком классе учится каждый ученик. Один класс объединяет многих учеников, поэтому сначала определим тип связи, а затем решим, где хранить ссылку. Это позволит не повторять сведения о классе целиком.
Ответ: внешний ключ размещают в таблице «Ученики» и связывают с первичным ключом «КодКласса» таблицы «Классы». Тогда у каждого ученика есть ссылка на его класс. При запросе по совпадающим кодам можно получить и сведения об ученике, и название класса.
Условие: у книги может быть несколько авторов, а один автор может написать несколько книг. Значит, ни одну из таблиц нельзя снабдить единственным внешним ключом так, чтобы охватить все случаи. Нужно представить каждую пару «книга — автор» отдельной записью.
Ответ: связь «многие ко многим» представляют через таблицу «АвторыКниг». Если у книги три автора, для неё создают три строки-связи; если автор написал несколько книг, его код повторяется в разных строках. При необходимости пару кодов можно использовать вместе, чтобы не записать одну и ту же связь дважды.
Ошибка — назначить первичным ключом поле, значения которого могут повторяться. Так бывает, когда выбирают фамилию или название, считая их уникальными, хотя у разных записей они могут совпасть. Проверь себя: может ли по значению поля найтись ровно одна запись? Если нет, нужен другой ключ или сочетание нескольких полей.
Ошибка — путать первичный и внешний ключи, будто внешний ключ заменяет первичный. Это происходит потому, что оба поля содержат коды и участвуют в связи, но выполняют разные роли. Проверь себя: первичный ключ определяет запись в собственной таблице, а внешний ссылается на запись в другой. Удалять или менять первичный ключ только из-за наличия ссылки нельзя.
Ошибка — записать несколько значений внешнего ключа в одну ячейку для связи «один ко многим». Так пытаются уместить все классы или объекты в одной строке, но базе трудно искать отдельные значения и проверять их. Проверь таблицу: одна ячейка должна содержать одно значение поля. Для нескольких связанных записей нужны отдельные строки.
Ошибка — пытаться описать связь «многие ко многим» одним внешним ключом. Один автор может иметь много книг, и одна книга — много авторов, поэтому одного значения недостаточно. Проверь себя, задав вопрос, может ли каждый объект связываться сразу с несколькими объектами другой таблицы. Если да, добавь таблицу связей с внешними ключами обеих таблиц.
Для работы с многотабличной базой нужно знать, что такое таблица, запись и поле. Таблица хранит данные об объектах, запись описывает один объект, а поле — его характеристику. Без этого трудно понять, что именно связывают ключи.
Выбор первичного ключа опирается на умение находить уникальные значения и различать записи. Если два объекта могут иметь одинаковое значение поля, одного этого поля недостаточно для надёжного поиска. Иногда уникальным оказывается сочетание нескольких полей.
Связи нужны при проектировании баз данных и составлении запросов. Запросы позволяют отбирать записи и получать совместные сведения из разных таблиц по совпадающим ключам. Поэтому понимание связей помогает не только хранить данные, но и находить нужную информацию.
Зачем хранить данные в нескольких таблицах, а не в одной?
Если хранить всё в одной таблице, одни и те же сведения, например название класса, придётся повторять для каждого ученика. При изменении таких данных легко оставить разные версии. Разделение по смысловым объектам уменьшает дублирование, а связи позволяют получать общую информацию.
Может ли первичный ключ состоять из нескольких полей?
Да, первичным ключом может быть набор полей, если только их сочетание однозначно определяет запись. Например, в таблице участия в соревнованиях сочетание номера ученика и номера соревнования может отличать одну запись от другой. При этом каждое поле по отдельности может повторяться.
Обязательно ли внешний ключ должен иметь то же имя, что и первичный?
Нет, названия могут различаться. Главное, чтобы значение внешнего ключа соответствовало значению первичного ключа в связанной таблице. Одинаковые или понятные названия лишь помогают человеку быстрее увидеть связь.
Где хранить внешний ключ при связи «один ко многим»?
Обычно его помещают в таблицу на стороне «многие». Например, в таблице учеников хранится ключ класса, потому что одному классу соответствуют записи о многих учениках. Так для каждого ученика можно указать его класс.
Как представить связь «многие ко многим»?
Создают дополнительную таблицу связей. В ней хранят внешние ключи обеих исходных таблиц, а каждая запись задаёт одну пару связанных объектов. Так можно указать несколько авторов у книги и несколько книг у автора.
§ 34. Многотабличные базы данных