Skip to main content

Database Design Guide

Общие правила

  1. В качестве СУБД РЕКОМЕНДУЕТСЯ использовать PostgreSQL, за исключением случаев когда для реализации задач решаемых сервисом другая технология является объективно предпочтительнее.
info

Внедрение платформы может потенциально использовать MySQL вместо PostgreSQL. Однако, это потребует существенных доработок непосредственно в рамках этого внедрения. В ходе разработки платформы РЕКОМЕНДУЕТСЯ избегать специфичной для PostgreSQL функциональности чтобы не увеличивать размер этих потенциальных доработок.

PostgreSQL

  1. В названии всех объектов (базы данных, схемы, индексы, вью, столбцы, триггеры и т.д.) ДОЛЖНЫ использоваться только латинские символы в нижнем регистре, цифры и нижнее подчеркивание
  2. Название объекта ДОЛЖНО начинаться с буквы в нижнем регистре
  3. РЕКОМЕНДУЕТСЯ использовать только схему public. Это повышает взаимозаменяемость с MySQL, а также упрощает конфигурирование фреймворков вроде Laravel
  4. В качестве кодировки необходимо использовать UTF8
  5. РЕКОМЕНДУЕТСЯ организовывать аутентификацию таким образом чтобы каждое приложение/сервис имело своего собственного пользователя

Таблицы

  1. Название таблиц и представлений должно быть во множественном числе. Пример: users
  2. РЕКОМЕНДУЕТСЯ не использовать обобщённые названия для таблиц. Например types, statuses и другие слова, которые могут быть применимы в будущем к другим сущностям. В таких случаях лучше использовать префикс для уточнения. Пример customer_types
  3. В случаях, когда одна бизнес-сущность хранится в нескольких таблицах РЕКОМЕНДУЕТСЯ использовать общий префикс для дополнительных таблиц. Пример: products, product_images, 'product_property_values'
  4. Для составных названий только последнее ключевое существительное ДОЛЖНО быть во множественном числе. Пример: таблица для статусов товаров должна называться product_statuses. Неправильно: status_products, products_status, products_statuses
  5. Таблицы соединений (pivot tables) РЕКОМЕНДУЕТСЯ именовать соединяя единственное число сущностей и добавляя суффикс _links. Первым идёт название основной сущности. Пример: addresses, users -> user_address_links

Столбцы

  1. Таблица всегда ДОЛЖНА иметь первичный ключ
  2. Столбец являющиеся первичным ключом РЕКОМЕНДУЕТСЯ называть id
  3. Столбцы ссылающиеся на первичные ключи РЕКОМЕНДУЕТСЯ называть в формате [сущность в единственном числе]_[название столбца с первичным ключом]. Пример: для первичного ключа customers.id используем внешний ключ customer_id
    1. Если родительская сущность совпадает с текущей (рекурсивная связь, например дерево категорий) РЕКОМЕНДУЕТСЯ использовать префикс parent_. Пример: categories.parent_id
  4. Названия столбов НЕ ДОЛЖНЫ содержать в себе названия текущей таблицы. Пример в таблице products поле "тип" не должно называться products.product_type. Правильный вариант: products.type
  5. Для разных таблиц РЕКОМЕНДУЕТСЯ использовать одинаковые слова для обозначения одинаковых по смыслу столбцов. Пример: название во всех таблицах должно быть name, а не name, title, label и т.д.
  6. РЕКОМЕНДУЕТСЯ не использовать типовые названия для отличных по смыслу столбцов. Пример: не использовать is_active для других смыслов, кроме активности. Пример типовых названий см. ниже
Типовые названия столбцов
ПолеКомментарий
idИдентификатор
nameНазвание
codeСимвольный код сущности, обычно транслитерация названия
descriptionОписание
is_activeИтоговая активность сущности (для вывода на витрину, фиды и т.д.)
typeТип
statusСтатус
payloadjson с дополнительными данными
urlСылка на http ресурс
priceИтоговая цена с учётом всех скидок
costЦена до скидки
created_at и updated_atПоля по умолчанию в каждой таблице для хранения даты создания и обновления

При необходимости можно использовать суффиксы к типовым названиям. Например: description_full, name_public

Типы некоторых столбцов

ПолеРекомендуемы типКомментарийLaravel migration
idbigserial primary keyрекомендуется именно big

$table->id(); который внутри уже сам вызывает

$table->unsignedBigInteger('id');

внешний ключunsigned bigint

$table->unsignedBigInteger('client_id')->index();

ценаbigint в копейках$table->bigInteger('price');
перечисление (enum)varchar(255)$table->string('type');
Временные метки (created_at, updated_at, email_verified_at)timestamp без таймзоны

Временная метка должна быть в UTC

Рекомендуется создавать с c precision = 6, чтобы поддерживать точность до микросекунд

$table->timestamp('email_verified_at', 6);
Дата (для тех случаев когда нужна именно дата, а не временная метка события. Например - дата рождения пользователя)date$table->date('birthday');

Индексы и ограничения

  1. Название индекса/ограничения ДОЛЖНО соответствовать шаблону ([schema])_[table]_[column1]_[column2]_[type].

Если используется схема public, то её можно опустить.

type - тип индекса/ограничения:

  • pkey - первичный ключ;
  • foreign - внешний ключ;
  • unique - уникальный индекс;
  • index - неуникальный индекс;

Например, для таблицы public.refunds и столбца code получаем уникальный индекс refunds_code_unique

info

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

Представления (View)

  1. В названии представления необходимо использовать префикс v_
  2. В названии материализованного представления необходимо использовать префикс mv_

Хранимые процедуры, функции и триггеры

  1. В названии хранимых процедур необходимо использовать префикс sp_
  2. В названии функций необходимо использовать префикс fn_
  3. В названии триггеров необходимо использовать префикс tr_ и суффикс условия срабатывания триггера (insert, update, delete)

Не рекомендовано к использованию для реализации бизнес-логики

  1. Пользовательские типы
  2. Курсоры
  3. Триггеры
  4. Хранимые процедуры
  5. Функции