Перейти к содержимому
Основы проектирования БД

Основы проектирования БД

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

Введение: Строим фундамент для данных

Представьте, что вам поручили организовать архив компании. Вам привозят горы документов: договоры, счета, акты, письма, карточки клиентов. Как их разложить? Можно сваливать все в одну коробку – тогда найти что-то будет невозможно. Можно разложить по папкам “Клиенты”, “Договоры”, “Счета”. А внутри папок – по годам, по алфавиту.

Проектирование базы данных – это то же самое, только для цифрового мира. Вы решаете:

  • Какие “сущности” будут в вашей базе (клиенты, заказы, товары).
  • Какие “атрибуты” у этих сущностей (у клиента – имя, телефон, email).
  • Как эти сущности связаны между собой (один клиент может сделать много заказов).

Проектирование базы данных - это процесс создания структуры базы данных: определение того, какие данные будут храниться, как они будут организованы и как связаны между собой.

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

Этапы проектирования базы данных

Проектирование базы данных обычно проходит через три этапа.

Концептуальное проектирование

Самый верхний уровень. Мы не думаем о серверах, таблицах, типах данных. Мы думаем о предметной области на языке бизнеса.

Вопросы на этом этапе:

  • “Какие сущности есть в бизнесе?” (Клиент, Заказ, Товар, Сотрудник).
  • “Какие у них свойства?” (У клиента есть имя, телефон, адрес).
  • “Как они связаны?” (Клиент делает заказы. Заказ состоит из товаров).

Результат: ER-диаграмма (Entity-Relationship) – схема сущностей и связей.

Логическое проектирование

Мы начинаем думать о структуре данных, но еще не привязаны к конкретной СУБД. Определяем:

  • Какие будут таблицы.
  • Какие поля в каждой таблице.
  • Какие первичные ключи.
  • Какие связи между таблицами.

Результат: логическая схема базы данных (без привязки к конкретной технологии).

Физическое проектирование

Привязываемся к конкретной СУБД (PostgreSQL, MySQL, Oracle). Определяем:

  • Типы данных (INTEGER, VARCHAR, DATE…).
  • Индексы (что будем ускорять).
  • Ограничения (какие значения допустимы).
  • Параметры хранения.

Результат: готовая база данных, в которой можно создавать таблицы.

Сущности, атрибуты и связи

Это три кита, на которых держится проектирование баз данных.

Сущность (Entity)

Сущность – это объект реального мира, о котором мы хотим хранить данные. Сущность – это “что-то”, что имеет самостоятельное значение для бизнеса.

Примеры сущностей:

  • Клиент
  • Заказ
  • Товар
  • Сотрудник
  • Поставщик

В базе данных сущность обычно становится таблицей.

Атрибут (Attribute)

Атрибут – это свойство, характеристика сущности. То, что мы хотим знать о сущности.

Атрибуты сущности “Клиент”:

  • Имя
  • Телефон
  • Email
  • Адрес
  • Дата регистрации

В базе данных атрибут становится полем (столбцом) таблицы.

Связь (Relationship)

Связь показывает, как сущности соотносятся друг с другом.

Примеры связей:

  • “Клиент” и “Заказ”: один клиент может сделать много заказов.
  • “Заказ” и “Товар”: один заказ может содержать много товаров. Один товар может быть во многих заказах.

Типы связей между сущностями

Один-к-одному (One-to-One, 1:1)

Одной записи в сущности “А” соответствует ровно одна запись в сущности “Б”. И наоборот.

Примеры:

  • “Человек” и “Паспорт”. У одного человека один паспорт. У одного паспорта один владелец.
  • “Сотрудник” и “Кабинет”. У одного сотрудника один кабинет. В одном кабинете один сотрудник.

В базе данных: Используется редко. Обычно такие сущности объединяют в одну таблицу. Или делают две таблицы, где внешний ключ уникален.

Один-ко-многим (One-to-Many, 1:N)

Одной записи в сущности “А” соответствует много записей в сущности “Б”. Но записи в “Б” соответствует ровно одна запись в “А”.

Примеры:

  • “Клиент” и “Заказ”. Один клиент может сделать много заказов. Один заказ принадлежит одному клиенту.
  • “Категория” и “Товар”. Одна категория может содержать много товаров. Один товар принадлежит одной категории.

В базе данных: Самый распространенный тип. Реализуется добавлением внешнего ключа в таблицу “многих” (Заказы), который ссылается на первичный ключ таблицы “одного” (Клиенты).

Многие-ко-многим (Many-to-Many, M:N)

Многим записям в сущности “А” соответствует много записей в сущности “Б”.

Примеры:

  • “Заказ” и “Товар”. Один заказ может содержать много товаров. Один товар может быть во многих заказах.
  • “Студент” и “Курс”. Один студент учится на многих курсах. На одном курсе учится много студентов.

В базе данных: Реализуется через промежуточную таблицу (связующую). В этой таблице хранятся пары ключей из обеих таблиц.

Ключи в проектировании баз данных

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

Первичный ключ (Primary Key)

Уникальный идентификатор записи в таблице.

Требования к первичному ключу:

  • Уникальный (не может повторяться).
  • Не пустой (не может быть NULL).
  • Не меняется (или меняется очень редко).

Что может быть первичным ключом:

  • Природный ключ: естественное уникальное свойство. Номер паспорта, ИНН, email. Но email может измениться, ИНН есть не у всех.
  • Искусственный ключ (суррогатный): специально созданное поле, например, id, которое автоматически увеличивается. Это самый надежный и распространенный вариант.

Внешний ключ (Foreign Key)

Поле в одной таблице, которое ссылается на первичный ключ другой таблицы.

Зачем нужен внешний ключ:

  • Обеспечивает связь между таблицами.
  • Гарантирует целостность данных – нельзя сослаться на несуществующую запись.

Пример: В таблице “Заказы” есть поле client_id. Это внешний ключ, который ссылается на id в таблице “Клиенты”. СУБД не даст создать заказ с client_id = 999, если клиента с таким id не существует.

Потенциальный ключ (Candidate Key)

Поле или комбинация полей, которые могли бы быть первичным ключом, но вы выбрали другой.

Пример: У сотрудника есть id (искусственный ключ) и passport_number (природный уникальный). Оба – потенциальные ключи. Вы выбрали id в качестве первичного.

Что такое нормализация

Нормализация – это процесс устранения дублирования данных и обеспечения их целостности. Это одна из самых важных тем в проектировании баз данных.

Плохая структура (денормализованная)

Представьте, что вы храните заказы вместе с данными клиента в одной таблице.

order_idclient_nameclient_phoneorder_datetotal
101Иван Петров790012345672024-01-152500
102Иван Петров790012345672024-02-201800
103Мария Сидорова790076543212024-02-255000

Проблемы:

  • Если Иван Петров сменит телефон, придется обновлять все его заказы. Легко ошибиться и пропустить какой-то.
  • Если у Ивана Петрова будет 1000 заказов, его телефон будет храниться 1000 раз. Это трата места.
  • Можно случайно написать для одного заказа “Иван Петров”, а для другого “Иван П.” – это разные люди или один?

Хорошая структура (нормализованная)

Разделяем на две таблицы.

Таблица “Клиенты”:

client_idnamephone
1Иван Петров79001234567
2Мария Сидорова79007654321

Таблица “Заказы”:

order_idclient_idorder_datetotal
10112024-01-152500
10212024-02-201800
10322024-02-255000

Преимущества:

  • Телефон клиента хранится один раз. Обновили в одном месте – все заказы “увидели” новые данные.
  • Экономия места.
  • Нет риска рассинхрона.

Простые правила нормализации

  1. Каждая информация хранится в одном месте. Не дублируйте данные. Если телефон клиента нужен в заказе – храните ссылку на клиента, а не сам телефон.

  2. Каждая таблица описывает одну сущность. В таблице “Заказы” не должно быть полей “Имя клиента” и “Телефон клиента”. Это данные о другой сущности – клиенте.

Проектирование на примере интернет-магазина

Выделяем сущности

Какие объекты есть в нашем бизнесе?

  • Клиент – тот, кто покупает.
  • Заказ – то, что создает клиент.
  • Товар – то, что покупают.
  • Категория – группировка товаров.

ШОпределяем атрибуты

Клиент:

  • id (первичный ключ, искусственный)
  • имя
  • телефон
  • email
  • дата регистрации

Заказ:

  • id (первичный ключ)
  • client_id (внешний ключ на Клиента)
  • дата создания
  • статус (новый, оплачен, отгружен, доставлен)
  • итоговая сумма

Товар:

  • id (первичный ключ)
  • название
  • цена
  • category_id (внешний ключ на Категорию)
  • остаток на складе

Категория:

  • id (первичный ключ)
  • название
  • описание

Определяем связи

  • “Клиент” и “Заказ”: один-ко-многим (один клиент – много заказов).
  • “Категория” и “Товар”: один-ко-многим (одна категория – много товаров).
  • “Заказ” и “Товар”: многие-ко-многим (один заказ – много товаров, один товар – много заказов). Для этого нужна промежуточная таблица.

Создаем промежуточную таблицу для связи многие-ко-многим

Таблица “Заказы_Товары” (связующая):

  • order_id (внешний ключ на Заказ)
  • product_id (внешний ключ на Товар)
  • quantity (количество товара в заказе)

Основная структура готова. По ней уже можно создавать таблицы в СУБД.

Проверка знаний

Вопрос 1 из 4
Зачем нужно проектирование БД?
С чего обычно начинается проектирование БД?
Почему плохое проектирование БД дорого обходится?
Что особенно важно для аналитика в проектировании БД?

Вопросы, где были ошибки