-
Notifications
You must be signed in to change notification settings - Fork 0
Модель данных
Пусть n = 200 - максимальная длина строки.
Назначение: хранение информации о пользователе.
{
"id" : ObjectId(),
"mail" : "string",
"password" : "string",
"sex" : "string",
"birth_date": ISODate(),
"name" : "string",
"surname" : "string",
"phone_number" : "string",
"meetings" : [
{
"id" : ObjectId(),
"time" : ISODate(),
"psychologist_id" : ObjectId(),
"status" : "string",
}
],
"reviews" : [ObjectId()],
"transactions" : [ObjectId()],
}
Назначение: хранение информации о психологе.
{
"user" :
{
"id" : ObjectId(),
"mail" : "string",
"password" : "string",
"sex" : "string",
"birth_date": ISODate(),
"name" : "string",
"surname" : "string",
"phone_number" : "string",
"balance" : "number"
"meetings" : [
{
"id" : ObjectId(),
"time" : ISODate(),
"psychologist_id" : ObjectId(),
"status" : "string",
}
],
"reviews" : [ObjectId()],
},
"price" : "number",
"address" : "string",
"meeting_format" : "string",
"education": [{ "institution": "string", "degree": "string", "year_graduated": ISODate() }],
"work_experience": [{ "position": "string", "place": "string", "years": [ISODate()] }],
"language" : "string",
"articles" : [ObjectId()]
}
Назначение: хранение информации о сессии клиента с психологом.
{
"id" : ObjectId(),
"time" : ISODate(),
"user_id" : ObjectId(),
"psychologist_id" : ObjectId(),
"status" : "scheduled" | "completed" | "canceled",
}
Назначение: хранение информации об отзыве о психологе.
{
"id" : ObjectId(),
"content" : "string",
"user_id" : ObjectId(),
"psychologist_id" : ObjectId(),
"created_at": ISODate(),
"rating": "number"
}
Назначение: хранение информации о статьях.
{
"id" : ObjectId(),
"content" : "string",
"psychologist_id" : ObjectId(),
"created_at": ISODate(),
"updated_at": ISODate()
}
Назначение: хранение информации о транзакциях пользователя.
{
"id": ObjectId(),
"user_id": ObjectId(),
"amount": "number",
"created_at": ISODate()
}
Пусть пользователь будет создавать 1 отзыв, 1 встречу, а психолог будет писать 1 статью. И предположим, что на 1 психолога приходится 10 обычных пользователей.
User: 12 + n + 20 + 1 + 8 + 25 + 25 + 11 + 8 + 54 = 356
Psychologist: 12 + n + n + 7 + n + 8 + n + n + 356 + 12 = 1399
Meeting: 12 + 12 + 12 + 8 + 10 = 54
Review: 12 + 4 * n + 12 + 12 = 836
Article: 12 + 100 * n + 12 = 20024
Тогда при количестве пользователей равным
User: meeting, review_id Psychologist: user, article_id Meeting: user_id, psychologist_id
Тогда чистый объем:
Тогда избыточность:
Для создания любой модели обязательно существование модели User. При создании сущности Psychologist, в нее дублируется сущность User. При добавлении сущности Meeting, она дублируется в User. При добавлении Review или Article, в User добавляются их Object_Id.
{
"id" : 145341129389203813049493003,
"mail" : "0@mail",
"password" : "123456",
"sex" : "m",
"age" : 30,
"name" : "jo",
"surname" : "jones",
"phone_number" : "79998887766",
"balance" : 10000
"meetings" : [],
"reviews" : [],
}
{
"user": {
"id": ObjectId("654321abcdef1234567890ab"),
"mail": "[email protected]",
"password": "hashed_password",
"sex": "female",
"birth_date": ISODate("1985-04-15T00:00:00Z"),
"name": "Anna",
"surname": "Smith",
"phone_number": "+1234567890",
"balance": 2000,
"meetings": [
{
"id": ObjectId("607f1f77bcf86cd799439011"),
"time": ISODate("2023-10-31T09:00:00Z"),
"psychologist_id": ObjectId("654321abcdef1234567890ab"),
"status": "completed"
}
],
"reviews": [ObjectId("607f1f77bcf86cd799439022")]
},
"price": 1000,
"address": "",
"meeting_format": "online",
"education": [
{
"institution": "",
"degree": "",
"year_graduated": ISODate("2010-06-15T00:00:00Z")
},
],
"work_experience": [
{
"position": "Child Psychologist",
"place": "School District 15",
"years": [ISODate("2011-09-01T00:00:00Z"), ISODate("2018-06-01T00:00:00Z")]
},
],
"language": "English",
"articles": [ObjectId("607f1f77bcf86cd799439033")]
}
{
"id": ObjectId("607f1f77bcf86cd799439044"),
"time": ISODate("2024-11-01T15:30:00Z"),
"user_id": ObjectId("123456abcdef6543210980ab"),
"psychologist_id": ObjectId("654321abcdef1234567890ab"),
"status": "scheduled"
}
{
"id": ObjectId("607f1f77bcf86cd799439055"),
"content": "",
"user_id": ObjectId("123456abcdef6543210980ab"),
"psychologist_id": ObjectId("654321abcdef1234567890ab"),
"created_at": ISODate("2024-10-30T12:45:00Z"),
"rating": 5
}
{
"id": ObjectId("607f1f77bcf86cd799439066"),
"content": "...",
"psychologist_id": ObjectId("654321abcdef1234567890ab"),
"created_at": ISODate("2024-09-15T08:30:00Z"),
"updated_at": ISODate("2024-10-01T10:00:00Z")
}
{
"id": ObjectId("607f1f77bcf86cd799439077"),
"user_id": ObjectId("123456abcdef6543210980ab"),
"amount": 1000,
"created_at": ISODate("2024-10-31T13:15:00Z")
}
Текст запросов Количество запросов для совершения юзкейсов в зависимости от числа объектов в БД и прочих параметров Количество задействованных коллекций (если есть)
db.users.find({
role: "psychologist",
name: { $regex: "имя_психолога", $options: "i" }
})
- 1 запрос.
- 1 коллекция:
users
.
db.articles.findOne({ _id: ObjectId("id_статьи") })
- 1 запрос.
- 1 коллекция:
articles
.
db.users.findOne({ _id: ObjectId("id_пользователя") })
- 1 запрос.
- 1 коллекция:
users
.
db.meetings.find({ user_id: ObjectId("id_пользователя") })
- 1 запрос для всех случаев (маленькая, средняя, большая БД).
- 1 коллекция:
meetings
.
db.users.updateOne(
{ _id: ObjectId("id_пользователя") },
{ $set: { mail: "новый_email", phone_number: "новый_номер_телефона", name: "новое_имя" } }
)
- 1 запрос для всех случаев (маленькая, средняя, большая БД).
- 1 коллекция:
users
.
db.meetings.aggregate([
{ $match: { time: { $gte: new ISODate(new Date().setMonth(new Date().getMonth() - 1)) } } },
{ $group: { _id: "$psychologist_id", sessions_count: { $sum: 1 } } },
{ $sort: { sessions_count: -1 } },
{ $limit: 10 }
]);
- 1 запрос.
- 1 таблица:
meetings
.
db.transactions.aggregate([
{ $match: { timestamp: { $gte: new ISODate(new Date().setMonth(new Date().getMonth() - 1)) }, type: "credit" } },
{ $group: { _id: "$user_id", total_earnings: { $sum: "$amount" } } },
{ $sort: { total_earnings: -1 } },
{ $limit: 10 }
]);
- 1 запрос.
- 1 таблица:
transactions
.
db.meetings.aggregate([
{ $match: { status: "canceled" } },
{ $group: { _id: "$user_id", canceled_sessions: { $sum: 1 } } },
{ $sort: { canceled_sessions: -1 } },
{ $limit: 10 }
]);
- 1 запрос.
- 1 таблица:
meetings
.
Пусть n = 200 - максимальная длина строки.
Назначение: хранение информации о пользователе.
- id int(4)
- mail(n)
- password varchar(20)
- sex varchar(1)
- birth_date DATE
- name text(25)
- surname text(25)
- phone_number varchar(11)
- balance int(4)
- messengers JSONB
Назначение: хранение информации о психологе.
- user_id int(4)
- price int(4)
- address text(n)
- meeting_format enum(varchar(7)|varchar(6))
- education JSONB
- work_experience JSONB
- specialization text(n)
- language text(n)
Назначение: хранение информации о сессии клиента с психологом.
- time timestamp(8)
- user_id int(4)
- psychologist_id int(4)
- status ENUM ('scheduled', 'completed', 'canceled')
Назначение: хранение информации об отзыве о психологе.
- id int(4)
- content text(4*n)
- user_id int(4)
- psychologist_id int(4)
- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
- rating INT
Назначение: хранение информации о статьях.
- id int(4)
- content text(100*n)
- psychologist_id int(4)
- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
- updated_at TIMESTAMP
Назначение: хранение транзакций пользователя.
- id int(4)
- user_id int(4)
- amount int
- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
User: 4 + n + 20 + 1 + 4 + 25 + 25 + 11 + 4 = 294
Psychologist: 4 + n + n + 7 + n + 4 + n + n = 1019
Meeting: 8 + 4 + 4 + 10 = 26
Review: 4 + 4 * n + 4 + 4 = 812
Article: 4 + 100 * n + 4 = 20008
Пусть пользователь будет создавать 1 отзыв, 1 встречу, а психолог будет писать 1 статью. И предположим, что на 1 психолога приходится 10 обычных пользователей. Тогда при количестве пользователей равным
Psychologist: user_id int(4) Meeting: user_id int(4), psychologist_id int(4) Review: user_id int(4), psychologist_id int(4) Article: psychologist_id int(4)
Тогда чистый объем:
Тогда избыточность:
Для создания любой модели обязательно существование модели User. При добавлении других моделей дополнительные модели создаваться не будут.
id | password | sex | age | name | surname | phone_number | balance | |
---|---|---|---|---|---|---|---|---|
0 | 0@mail | 123456 | m | 30 | jo | jones | 79998887766 | 10000 |
1 | 0@mail | qwerty | w | 27 | sue | sunes | 75554443322 | 120000 |
user_id | price | address | meeting_format | education | work_experience | specialization | language |
---|---|---|---|---|---|---|---|
0 | 3000 | My Street, 8 | online | MIT | 5 | Gestalt therapy | russian |
Текст запросов Количество запросов для совершения юзкейсов в зависимости от числа объектов в БД и прочих параметров Количество задействованных коллекций (если есть)
SELECT *
FROM users
WHERE name ILIKE 'имя_психолога'
AND id IN (SELECT user_id FROM psychologists);
- 1 запрос.
- 2 таблицы:
users
,psychologists
.
SELECT *
FROM articles
WHERE id = id_статьи;
- 1 запрос.
- 1 таблица:
articles
.
SELECT *
FROM users
WHERE id = id_пользователя;
- 1 запрос.
- 1 таблица:
users
.
SELECT *
FROM meetings
WHERE user_id = id_пользователя;
- 1 запрос.
- 1 таблица:
meetings
.
UPDATE users
SET mail = 'новый_email', phone_number = 'новый_номер_телефона', name = 'новое_имя'
WHERE id = id_пользователя;
- 1 запрос.
- 1 таблица:
users
.
SELECT psychologist_id, COUNT(*) AS sessions_count
FROM meetings
WHERE time >= (CURRENT_DATE - INTERVAL '1 month')
GROUP BY psychologist_id
ORDER BY sessions_count DESC
LIMIT 10;
- 1 запрос.
- 1 таблица:
meetings
.
SELECT psychologist_id, SUM(amount) AS total_earnings
FROM transactions
WHERE timestamp >= (CURRENT_DATE - INTERVAL '1 month')
GROUP BY psychologist_id
ORDER BY total_earnings DESC
LIMIT 10;
- 1 запрос.
- 1 таблица:
transactions
.
SELECT user_id, COUNT(*) AS canceled_sessions
FROM meetings
WHERE status = 'canceled'
GROUP BY user_id
ORDER BY canceled_sessions DESC
LIMIT 10;
- 1 запрос.
- 1 таблица:
meetings
.
Реляционная модель (PostgreSQL):
- Для сохранения объектов в реляционной модели требуется меньше памяти из-за отсутствия дублирования данных.
Нереляционная модель (MongoDB):
- В MongoDB наблюдается некоторая избыточность данных, так как сущности, например,
User
иPsychologist
, дублируют информацию друг друга. Это увеличивает объем хранимых данных, особенно когда психологи дублируют данные пользователей.
Вывод: В реляционной модели данные занимают меньший объем при прочих равных, так как она структурирована с минимальной избыточностью.
Реляционная модель:
- Количество запросов: 1 запрос.
-
Количество коллекций: 2 таблицы (
users
иpsychologists
).
Нереляционная модель:
- Количество запросов: 1 запрос.
-
Количество коллекций: 1 коллекция (
users
).
Вывод: MongoDB требует обращения только к одной коллекции, что может быть быстрее при меньших затратах на операции соединения.
Реляционная модель:
- Количество запросов: 1 запрос.
-
Количество коллекций: 1 таблица (
articles
).
Нереляционная модель:
- Количество запросов: 1 запрос.
-
Количество коллекций: 1 коллекция (
articles
).
Вывод: Оба подхода идентичны по эффективности при выполнении данного запроса.
Реляционная модель:
- Количество запросов: 1 запрос.
-
Количество коллекций: 1 таблица (
users
).
Нереляционная модель:
- Количество запросов: 1 запрос.
-
Количество коллекций: 1 коллекция (
users
).
Вывод: Оба подхода равны по количеству запросов и эффективности.
Реляционная модель:
- Количество запросов: 1 запрос.
-
Количество коллекций: 1 таблица (
meetings
).
Нереляционная модель:
- Количество запросов: 1 запрос.
-
Количество коллекций: 1 коллекция (
users
, так как встречи вложены в документ пользователя).
Вывод: В MongoDB встречи хранятся внутри документа пользователя, что позволяет избежать дополнительных обращений к коллекциям. Это упрощает запросы и может ускорить их выполнение.
Реляционная модель:
- Количество запросов: 1 запрос.
-
Количество коллекций: 1 таблица (
users
).
Нереляционная модель:
- Количество запросов: 1 запрос.
-
Количество коллекций: 1 коллекция (
users
).
Вывод: Оба подхода идентичны по количеству запросов и эффективности.
Для данного проекта наиболее подходящей будет MongoDB (NoSQL). Она обеспечивает гибкость в структуре данных, высокую производительность при работе с вложенными документами и легкость в масштабировании. Это особенно важно в условиях частых изменений в структуре данных и необходимости обрабатывать большие объемы информации, связанных с психологами, пользователями, встречами и отзывами.