Структура сущностей
1. Описание абстрактной базы данных
Ниже представлена абстрактная структура базы данных. Реальную базу данных генерирует наш backend-фреймворк strapi, и реальная база несколько отличается от абстрактной. Схема реальной базы будет представлена в конце раздела.
2. Структура сущностей
В админ-панели strapi представлены следующие сущности: Box, Location, BroadcastPackage, MasterType, Master, Advertisement, Content, MediaThemes, MediaFile, Media, User.
Box - сущность, описывающая приставку Raspberry Pi. Каждая приставка имеет uuid и связана с Location - местонахождением устройства (один ко многим: одна локация -> много приставок на локации).
Location - сущность, описывающая локацию. Имеет адрес и связь с Master (один ко многим: один мастер -> много ссылающихся на него локации)
Master - структура, описывающее вещание на определенной локации. Состоит из записей Advertisements и * Contents* (Advertisement и Content ссылаются на конкретный мастер, у отдельного Advertisement или Content может быть только один Master). Также мастер имеет название, тип MasterType (связь с MasterType - один ко многим: один тип, может быть у многих мастеров), и связь с BroadcastPackage (многие ко многим: один мастер может быть в нескольких пакетах вещания, и в одном пакете вещания может быть множество мастеров)
MasterType - перечисление, описывающее тип той локации, к которой относится мастер (важно, что на MasterType ссылается именно Master, а не Location). Примеры типов локаций: ресторан, спа-салон, отель и т. п.
BroadcastPackage - сущность, описывающая пакет вещания. Состоит из множества мастеров. Эти множества могут пересекаться, или одно множество может включать в себя другое. Примеры пакетов вещания: "Фитнес-клубы", "Фитнес-клубы с бьюти услугами", "Фитнес-клубы с бьюти-услугами Москва/МО", "Фитнес-клубы Москва/МО". На этих примерах легко видны включения и пересечения множеств. Таким образом, связь между BroadcastPackage и Master - многие ко многим.
Advertisement и Content - сущности, описывающие поведение роликов в мастерах. Все ролики в системе делятся на два типа: рекламные и контентные. Соответствующие сущности описывают данные типы. Контентные ролики нужны, чтобы разбавить вещание красивыми отвлекающими роликами про путешествия, моду, интересные факты и т. п. Advertisement и Content ссылаются на MediaFile (связь один ко многим: на один ролик может ссылаться множество Advertisements или Contents). Также данные сущности содержат информацию о дате начала вещания ролика, о дате конца вещания, повторять ли вещание ежемесячно, ссылку на мастер, в котором будет проигрываться данная реклама или контент. Сущность Advertisement содержит информацию о количестве показов ролика за 6 часов (это только для рекламы). Больше данные сущности не отличаются ничем. Также, данные сущности дублируют информацию из MediaFile и хранят название и длительность медиафайла, на который ссылаются. Такое нарушение нормализации нужно для упрощения алгоритмов вывода, фильтра и сортировки Advertisements и Contents.
MediaFile - сущность, описывающая файл mp4 с рекламой или контентом. Имеет поле type, которое говорит, реклама это или контент. Имеет ссылку на структуру Media - это структура, описанная внутри strapi, интегрированная с файловым хранилищем. Эта структура ссылается уже на сам медиафайл и содержит информацию о его размере, хэше (поле hash формата имя_файла_6be1af30fb), имени исходного файла и т. д. MediaFile дублирует некоторую информацию из этой структуры, вроде size и hash (поле md5 в MediaFile). Это нужно также для удобства фильтра, сортировки и т. д. Обращаем внимание, что поле name внутри Media и name внутри MediaFile - это разные поля. Поле name в media - это название исходного медиафайла, и зависит только от самого файла, а такое же поле name внутри MediaFile - это название файла внутри медиасервера. Также MediaFile может ссылаться на MediaTheme - папку, в которой находится MediaFile.
MediaTheme - сущность, описывающая папку, в которой могут находиться медиафайлы. Связь MediaTheme и MediaFile - один ко многим: на одну папку могут ссылаться множество медиафайлов. MediaTheme имеет название и ссылку на родительский MediaTheme. Таким образом, получается обычная иерархическая система каталогов.
User - сущность, описывающая пользователя.
Обратите внимание, что сущности в strapi могут иметь как односторонние, так и двусторонние связи. Все связи будут описаны ниже в типе Relation with...
Сущность Box (Устройство)
Поле | Тип | Описание |
|---|---|---|
uuid | Text | Уникальный uuid устройства |
monitorsQuantity | Number | Количество мониторов, подключенных к данному устройству |
location | Relation with Location | Связь с локацией |
Сущность Location (Локация)
Поле | Тип | Описание |
|---|---|---|
name | Text | Название заведения |
address | Text | Адрес заведения |
master | Relation with Master | Связь с мастером |
boxes | Relation with Box | Связь с устройствами, ссылающимися на эту локацию |
Сущность Master (мастер)
Поле | Тип | Описание |
|---|---|---|
name | Text | Название |
locations | Relation with Location | Связи с локациями |
advertisements | Relation with Advertisement | Связи с информацией о рекламах |
contents | Relation with Content | Связь с информацией о контенте |
masterType | Relation with Master Type | Связь с типом Master |
order | Number | Порядковый номер Мастера |
broadcastPackages | Relation with Broadcast Packages | Связь с пакетами вещания |
Сущность Master Type (тип мастера)
Поле | Тип | Описание |
|---|---|---|
name | Text | Название типа |
masters | Relation with Master | Связь с мастерами |
Сущность Broadcast Package (пакет вещания)
Поле | Тип | Описание |
|---|---|---|
name | Text | Название пакета вещания |
masters | Relation with Master | Связь с мастерами |
Сущность Advertisement (реклама)
Поле | Тип | Описание |
|---|---|---|
frequency | Number | Частота показов в 6 часов |
startAt | Datetime | Дата начала показа данной рекламы |
stopAt | Datetime | Дата конца показа данной рекламы |
mediaFile | Relation with Media File | Ссылка на MediaFile |
isEveryMonth | Boolean | Флаг, показывать ли рекламу ежемесячно |
master | Relation with Master | Ссылка на мастер, в котором будет эта реклама |
duration | Number | Длительность рекламы (поле дублирует duration в MediaFile) |
name | Text | Название рекламы (поле дублирует name в MediaFile) |
Сущность Content (контент)
Поле | Тип | Описание |
|---|---|---|
startAt | Datetime | Дата начала показа данного контента |
stopAt | Datetime | Дата конца показа данного контента |
mediaFile | Relation with Media File | Ссылка на MediaFile |
isEveryMonth | Boolean | Флаг, показывать ли контент ежемесячно |
master | Relation with Master | Ссылка на мастер, в котором будет этот контент |
duration | Number | Длительность контента (поле дублирует duration в MediaFile) |
name | Text | Название контента (поле дублирует name в MediaFile) |
Сущность Media File (медиафайл)
Поле | Тип | Описание |
|---|---|---|
media | Media | ссылка на исходный файл с информацией |
name | Text | Название |
type | Enumeration | Тип (реклама или контент) |
duration | Number | Длительность |
md5 | Text | MD5-хеш (дублирует поле hash из структуры Media) |
size | Number | Размер |
advertisements | Relation with Advertisements | Связи с ссылающимися на данный файл Advertisements |
contents | Relation with Contents | Связи с ссылающимися на данный файл Contents |
mediaTheme | Relation with Media Themes | Связь с категорией (или папкой) |
Сущность Media Theme (категория/папка)
Поле | Тип | Описание |
|---|---|---|
name | Text | Название темы |
childThemes | Relation with Media Themes | Связь с дочерними категориями |
parentTheme | Relation with Media Themes | Связь с родительской категорией |
mediaFiles | Relation with Media File | Связь с медиафайлами, которые лежат в этой категории |
Сущность User
Поле | Тип | Описание |
|---|---|---|
username | Text | Имя пользователя |
Электронная почта | ||
provider | Text | Провайдер аутентификации |
password | Password | Пароль |
resetPasswordToken | Text | Токен для сброса пароля |
confirmationToken | Text | Токен подтверждения регистрации |
confirmed | Boolean | Подтвержден ли пользователь |
blocked | Boolean | Заблокирован ли пользователь |
role | Relation with Role (from: users-permissions) | Роль пользователя |
3. ER-диаграмма базы данных
Сущности, описанные выше, настраиваются в admin-панели strapi, после чего на основе этих сущностей strapi формирует реальную базу данных. Основное отличие реальной базы данных от сущностей, описанных выше, состоит в том, что связи между сущностями описаны в отдельных таблицах. Также в отдельных таблицах хранятся роли пользователей и их доступы к действиям с определенными сущностями (засчет этого permissions в strapi настраиваются гибко).

Рисунок 1: ER-диаграмма базы данных