-
Notifications
You must be signed in to change notification settings - Fork 0
Модель данных
Хранинеие информации об объявлениях
{
"title": "Announcement",
"description": "Коллекция объявлений",
"type": "object",
"properties": {
"creation_date": {
"description": "Дата публикации",
"type": "number"
},
"content": {
"description": "Содержимое объявления",
"type": "string"
},
"tag": {
"description": "Ассоциированный тэг",
"type": "string"
}
},
"required": ["creation_date", "content", "tag"]
}
Суммарный объем данных: 530 байт.
Хранение информации о комментариях к объявлениям
{
"title": "Comment",
"description": "Коллекция комментариев",
"properties": {
"creation_date": {
"description": "Дата создания",
"type": "number"
},
"content": {
"description": "Содержимое комментария",
"type": "string"
}
},
"required": ["creation_date", "content"]
}
Суммарный объем данных: 241 байт.
Хранение информации о группах
{
"title": "Group",
"description": "Коллекция групп",
"properties": {
"name": {
"description": "Название группы",
"type": "string"
},
"creation_date": {
"description": "Дата создания",
"type": "number"
},
"last_edit_date": {
"description": "Дата последнего изменения",
"type": "number"
},
"avatar_uri": {
"description": "Ссылка на аватар",
"type": "string"
},
"genres": {
"description": "Список жанров группы",
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
}
},
"required": ["name", "creation_date", "last_edit_date", "avatar_uri", "genres"]
}
Суммарный объем данных: 348 байт.
Хранение информации о местах
{
"title": "Place",
"description": "Коллекция мест",
"properties": {
"user_id" : {
"description": "Идентификатор пользователя-создателя",
"type": "string"
},
"name": {
"description": "Название места",
"type": "string"
},
"creation_date": {
"description": "Дата создания",
"type": "number"
},
"last_edit_date": {
"description": "Дата последнего изменения",
"type": "number"
},
"avatar_uri": {
"description": "Ссылка на аватар",
"type": "string"
},
"type": {
"description": "Тип места",
"type": "string"
},
"address": {
"description": "Адрес места",
"type": "string"
},
"phone_number": {
"description": "Контактный номер",
"type": "string"
},
"area": {
"description": "Площадь",
"type": "number"
},
"equipment": {
"description": "Список оборудования",
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"description": "Название оборудования",
"type": "string"
},
"amount": {
"description": "Количество оборудования",
"type": "number"
}
},
"required": ["name", "amount"]
},
"uniqueItems": true
}
},
"required": ["user_id", "name", "creation_date", "last_edit_date", "avatar_uri", "type", "address", "phone_number", "area", "equipment"]
}
Суммарный объем данных: 1572 байт.
Хранение информации об отношениях между создателями объявлений и объявлениями
{
"title": "ProducerAnnouncement",
"description": "Коллекция отношений между создателями объявлений и объявляениями"
}
Суммарный объем данных: 66 байт.
Хранение информации о поставленных звездах
{
"title": "Stars",
"description": "Коллекция звезд"
}
Суммарный объем данных: 41 байт.
Хранение информации о статичных данных
{
"title": "Static",
"description": "Коллекция статичных данных",
"properties": {
"equipment" : {
"description": "Список доступного оборудования",
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
},
"tags" : {
"description": "Список доступных тегов",
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
},
"talents" : {
"description": "Список доступных талантов",
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
},
"genres" : {
"description": "Список доступных жанров",
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
}
},
"required": ["equipment", "tags", "talents", "genres"]
}
Суммарный объем данных: 8200 байт.
Хранение информации о пользователе
{
"title": "User",
"description": "Коллекция пользователей",
"properties": {
"first_name": {
"description": "Имя пользователя",
"type": "string"
},
"last_name": {
"description": "Фамилия пользователя",
"type": "string"
},
"creation_date": {
"description": "Дата создания",
"type": "number"
},
"last_edit_date": {
"description": "Дата последнего изменения",
"type": "number"
},
"avatar_uri": {
"description": "Ссылка на аватар",
"type": "string"
},
"talents": {
"description": "Список жанров группы",
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
}
},
"required": ["first_name", "first_name", "creation_date", "last_edit_date", "avatar_uri", "talents"]
}
Суммарный объем данных: 492 байт.
Хранение информации об отношениях между пользователями и группами
{
"title": "UserGroup",
"description": "Коллекция отношений между пользователями и группами",
"properties": {
"join_date": {
"description": "Дата присоединения пользователя к группе",
"type": "number"
}
}
"required": ["join_date"]
}
Суммарный объем данных: 32 байта.
В качестве переменной используется количество пользователей
Таблица Static не зависит от числа пользователей, хранится в единственном экземпляре и имеет размер 8200 байт.
Количество групп выразим через количество пользователей как
Для каждого пользователя приходится в среднем 2 таланта, 30 объявлений, 500 звезд суммарно, 50 комментариев, 2 места. У каждого места в среднем по 10 различных видов оборудования.
Для каждой группы приходится 30 объявлений и 2 жанра.
Тогда примерный объем модели можно выразить следующей формулой:
Избытычность заключается в следующем:
- В разных группах могут быть записаны одни и те же жанры
- В разных местах может быть записано одно и то же оборудование
- У разных пользователей могут быть записаны одни и те же таланты
- Теги объявлений могут быть закодированы числом
Коэффицент избыточности:
- Если растет количество документов, то растет число вершин в графе.
- Если растет количество связей между документами, то связность графа увеличивается.
[
{
"_key": "4769",
"_id": "User/4769",
"_rev": "_ioED4LW---",
"first_name": "Andrey",
"last_name": "Babenko",
"creation_date": "2021-01-01",
"last_edit_date": "2022-01-01",
"avatar_uri": "assets/avatars/andrey.png",
"talents": [
"electric-guitar"
]
},
{
"_key": "477",
"_id": "User/477",
"_rev": "_ioTzDnK---",
"first_name": "Thomas",
"last_name": "York",
"creation_date": "2020-01-01",
"last_edit_date": "2024-10-19T15:46:07.123Z",
"avatar_uri": "assets/avatars/thomas-new.png",
"talents": [
"vocal",
"acoustic-guitar",
"electric-guitar"
]
},
{
"_key": "863",
"_id": "User/863",
"_rev": "_ioDTZXm---",
"first_name": "Egor",
"last_name": "Letov",
"creation_date": "2021-01-01",
"last_edit_date": "2022-01-01",
"avatar_uri": "assets/avatars/egor.png",
"talents": [
"vocal",
"acoustic-guitar",
"electric-guitar",
"drums"
]
}
]
[
{
"_key": "1553",
"_id": "Announcement/1553",
"_rev": "_ioDb1Ru---",
"content": "Сегодня концерт!",
"creation_date": "2024-10-18",
"tag": "concert"
},
{
"_key": "1593",
"_id": "Announcement/1593",
"_rev": "_ioDcOf2---",
"content": "Пьяных не пускаем, даже по причине пятницы!",
"creation_date": "2024-10-18",
"tag": "concert"
}
]
- Самая популярная группа
FOR g in Group
LET stars_amount = (
FOR s IN Stars
FILTER s._to == g._id
COLLECT WITH COUNT INTO amount
RETURN amount
)[0]
SORT stars_amount DESC
LIMIT 1
RETURN {
_id: g._id,
name: g.name,
stars_amount: stars_amount
}
- Места с типом "Концертная точка"
FOR p IN Place
FILTER p.type == "Концертная точка"
RETURN p
- Редактирование данных профиля пользователем
LET key = PARSE_IDENTIFIER("User/477").key
UPDATE key
WITH {
first_name: "Thomas",
last_name: "York",
last_edit_date: DATE_FORMAT(DATE_NOW(), "%yyyy-%mm-%ddT%hh:%ii:%ss.%fffZ"),
avatar_uri: "assets/avatars/thomas-new.png"
}
IN User
RETURN NEW
- Записи с тегом "концерт" (в порядке уменьшения звезд на них)
FOR a in Announcement
LET stars_amount = (
FOR s IN Stars
FILTER s._to == a._id
COLLECT WITH COUNT INTO amount
RETURN amount
)[0]
SORT stars_amount DESC
RETURN MERGE(a, {
stars_amount: stars_amount
})
- Все анонсы пользователя
FOR pa IN ProducerAnnouncement
FILTER pa._from == @userId
FOR a IN Announcement
FILTER pa._to == a._id
RETURN a
- Все комментарии пользователя
FOR c IN Comments
FILTER c._from == @userId
RETURN c
- Все авторы комментариев к определенному анонсу
FOR a IN Announcement
FILTER a._id == @ann_id
FOR c IN Comment
FILTER c._to == a._id
FOR u IN User
FILTER c._from == u._id
RETURN u
- Все группы, чьи пользователи поставили звезду на определенный анонс
FOR s IN Star
FILTER s._to == @ann_id
FOR ug IN UserGrop
FILTER ug._from == s._from
FOR g in Group
FILTER ug._to == g._id
RETURN g
Информация о пользователе
- id: INT NOT NULL
- first_name: VARCHAR
- last_name: VARCHAR
- creation_data: DATETIME
- last_edit_date: DATETIME
- avatar_uri: VARCHAR
Суммарный объем данных: 785 байт.
Информация о полученных звездах пользователя
- source_user_id: INT NOT NULL
- destination_user_id: INT NOT NULL
Суммарный объем данных: 8 байт.
Информация о музыкальных талантах пользователя
- user_id: INT NOT NULL
- talent_id: INT NOT NULL
Суммарный объем данных: 8 байт.
Информация о группе, в которой состоит пользователь
- user_id: INT NOT NULL
- group_id: INT NOT NULL
- join_date: DATETIME
Суммарный объем данных: 16 байт.
Информация об объявлении, которое получает пользователь
- user_id: INT NOT NULL
- announcement_id: INT NOT NULL
Суммарный объем данных: 8 байт.
Информация о музыкальном таланте
- id: INT NOT NULL
- name: VARCHAR
Суммарный объем данных: 259 байт.
Информация о группе
- id: INT NOT NULL
- name: VARCHAR
- creation_date: DATETIME
- last_edit_date: DATETIME
- avatar_uri: VARCHAR
Суммарный объем данных: 530 байт.
Информация об объявлении группы
- group_id: INT NOT NULL
- announcement_id: INT NOT NULL
Суммарный объем данных: 8 байт.
Информация о полученных звездах группы
- source_user_id: INT NOT NULL
- destination_group_id: INT NOT NULL
Суммарный объем данных: 8 байт.
Информация о жанрах группы
- group_id: INT NOT NULL
- genre_id: INT NOT NULL
Суммарный объем данных: 8 байт.
Информация о всех жанрах
- id: INT NOT NULL
- name: VARCHAR
Суммарный объем данных: 259 байт.
Информация об объявлении
- id: INT NOT NULL
- tag_id: INT NOT NULL
- content: VARCHAR
- creation_date: DATETIME
Суммарный объем данных: 271 байт.
Информация о звездах объявление
- source_user_id: INT NOT NULL
- destination_announcement_id: INT NOT NULL
Суммарный объем данных: 8 байт.
Информация о комментарии
- id: INT NOT NULL
- user_id: INT NOT NULL
- announcement_id: INT NOT NULL
- content: VARCHAR
- creation_date: DATETIME
Суммарный объем данных: 275 байт.
Информация о теге
- id: INT NOT NULL
- name: VARCHAR
Суммарный объем данных: 259 байт.
Информация о месте, репточке
- id: INT NOT NULL
- user_id: INT NOT NULL
- name: VARCHAR
- creation_date: DATETIME
- last_edit_date: DATETIME
- type: VARCHAR
- address: VARCHAR
- phone_number: VARCHAR
- area: DOUBLE
Суммарный объем данных: 1052 байт.
Информация об оборудовании
- id: INT NOT NULL
- name: VARCHAR
Суммарный объем данных: 259 байт.
Информация об оборудовании, доступном на репитиционных точках
- place_id: INT NOT NULL
- equipment_id: INT NOT NULL
- amount: INT
Суммарный объем данных: 12 байт.
В качестве переменной используется количество пользователей
Таблицы Tag, Talent, Equipment и Genre не зависят от числа пользователей (имеют 50, 20, 20 и 20 объектов соответственно) и имеют размеры 12950 байт, 5180 байт, 5180 байт и 5180 соответственно.
Количество групп выразим через количество пользователей как
Для каждого пользователя приходится в среднем 2 таланта, 30 объявлений, 500 звезд суммарно, 50 комментариев, 2 места. У каждого места в среднем по 10 различных видов оборудования.
Для каждой группы приходится 30 объявлений и 2 жанра.
Тогда примерный объем модели можно выразить следующей формулой:
В построенной реляционной модели отсутствуют повторяющиеся поля, все идентификаторы задействованы для установления связей между сущьностями, поэтому в построенной модели отсутствует избыточность.
id | first_name | last_name | creation_date | last_edit_date | avatar_url |
---|---|---|---|---|---|
1 | Victor | Tsoy | 1982-06-06 00:00:00 | 1990-08-15 00:00:00 | tsoy.png |
2 | Egor | Letov | 1982-11-11 00:00:00 | 2008-02-19 00:00:00 | letov.png |
id | tag_id | content | creation_date |
---|---|---|---|
123 | 1234 | Сегодня концерт! | 2024-10-18 00:00:00 |
124 | 1234 | Пьяных не пускаем, даже по причине пятницы! | 2024-10-18 00:00:00 |
- Самая популярная группа
SELECT g.id, g.name, COUNT(gs.source_user_id) AS star_count
FROM Group g
LEFT JOIN GroupStars gs ON g.id = gs.destination_group_id
GROUP BY g.id, g.name
ORDER BY star_count DESC
LIMIT 1;
- Места с типом "Концертная точка"
SELECT *
FROM Places
WHERE type = "Концертная точка"
- Редактирование данных профиля пользователем
UPDATE User
SET
first_name = NEW.first_name,
last_name = NEW.last_name,
creation_date = NEW.creation_date,
last_edit_date = now(),
avatar_url = NEW.avatar_url
WHERE id = NEW.id;
- Записи с тегом "концерт" (в порядке уменьшения звезд на них)
SELECT a.*, COUNT(as.id) AS star_count
FROM Announcements a
LEFT JOIN AnnouncementsStars as ON a.id = as.destination_announcements_id
WHERE a.tag_id = (SELECT id FROM Tags WHERE tag_name = 'концерт')
GROUP BY a.id
ORDER BY star_count DESC;
- Все объявления пользователя
SELECT Announcement.* FROM Announcement
JOIN UserAnnouncement ON Announcement.id = UserAnnouncement.announcement_id
WHERE UserAnnouncement.user_id = 0;
- Все комментарии пользователя
SELECT * FROM Comments
WHERE user_id = 0;
- Все авторы комментариев к определенному объявлению
SELECT DISTINCT User.* FROM User
JOIN Comment ON User.id = Comment.user_id
WHERE Comment.announcement_id = 0;
- Все группы, чьи пользователи поставили звезду к заданному объвлению
SELECT DISTINCT Group.* FROM Group
JOIN UserGroup ON UserGroup.group_id = Group.id
JOIN AnnouncementStars ON UserGroup.user_id = AnnouncementStars.source_user_id
WHERE AnnouncementStars.destination_announcement_id = 1;
NoSQL - 8200 + 65022 * U байт.
SQL - 28490 + 34560 * U байт.
NoSQL будет требовать значительно больше памяти, чем SQL-решение.
Количество запросов для совершения юзкейсов в зависимости от числа объектов в БД и прочих параметров
- NoSQL - 2 запроса.
- SQL - 1 запрос.
- NoSQL - 1 запрос.
- SQL - 1 запрос.
- NoSQL - 1 запрос.
- SQL - 2 запроса.
- NoSQL - 2 запроса.
- SQL - 1 запрос.
- NoSQL - 2 коллекции.
- SQL - 2 таблицы.
- NoSQL - 1 коллекция.
- SQL - 1 таблица.
- NoSQL - 1 коллекция.
- SQL - 2 таблицы.
- NoSQL - 2 коллекции.
- SQL - 2 таблицы.
- Удобнее использовать NoSQL так как необходимо реализовывать множество связей "многие ко многим".
- NoSQL требует значительно больше памяти, чем SQL-решение.
- Количество запросов и задействованных коллекций в NoSQL и SQL примерно равны.