-
Notifications
You must be signed in to change notification settings - Fork 0
Модель данных
_id: ObjectID,
name: String,
surname: String,
email: String,
password: String,
orders: Array of ObjectID,
phone: String,
image: String,
createdAt: Date,
editedAt: Date
}
_id: ObjectID,
tools: Array of Object,
startLeasing: Date (dd/mm/yyyy),
endLeasing: Date (dd/mm/yyyy),
price: Double,
client: Object,
deliveryType: String,
deliveryState: String,
paymentType: String,
paymentState: String,
createOrderTime: Date (dd/mm/yyyy hh:min),
relatedWorker: Object
}
_id: ObjectID,
name: String,
surname: String,
email: String,
phone: String,
image: String,
jobTitle: String,
state: String,
date: Date (dd/mm/yyyy),
orders: Array of Object,
createdAt: Date,
editedAt: Date
}
_id: ObjectID,
name: String,
dailyPrice: Double,
images: Array of String,
features: Array of String,
reviews: Array of ObjectID,
rating: Double,
ordersNumber: int32,
category: String,
type: String,
description: String
totalPrice: Double
createdAt: Date
editedAt: Date
}
_id: ObjectID,
toolId: ObjectID,
reviewerId: ObjectID,
rating: Double,
date: Date (dd/mm/yyyy),
text: String
}
- _id - уникальный идентификатор клиента;
- name - имя клиента;
- surname - фамилия клиента;
- email - почта клиента;
- password - пароль клиента;
- orders - заказы клиента;
- phone - контактный телефон клиента;
- image - изображение клиента в виде URI ссылки;
- createdAt - дата создания аккаунта;
- editedAt - дата последнего изменения аккаунта;
- _id - уникальный идентификатор заказа;
- tools - список инструментов в заказе;
- toolName - наименование инструмента;
- toolNumber - идентификатор инструмента;
- startLeasing - дата начала аренды;
- endLeasing - дата окончания аренды;
- price - цена заказа;
- client - клиента, сделавший заказ;
- name - имя
- surname - фамилия
- phone - номер телефона
- deliveryType - тип доставки (SELFPICKUP, DOOE_DELIVERY);
- deliveryState - статус доставки (IN_WAREHOUSE, ON_WAY, DELIVERED, PICKED_UP);
- paymentType - тип оплаты (CASH, CARD, SBP);
- paymentState - статус оплаты (NOT_PAID, PAID, IN_PROCESS);
- createOrderTime - время создания заказа;
- relatedWorker - работник, отвечающий за заказ;
- name - имя
- surname - фамилия
- phone - номер телефона
- _id - уникальный идентификатор работника;
- name - имя работника;
- surname - фамилия работника;
- email - почта работника;
- phone - контактный телефон работника;
- image - изображение клиента в виде URI ссылки;
- jobTitle - должность;
- state - текущий статус работника;
- date - дата начала работы;
- orders - заказы работника;
- orderNumber - номер заказа
- tools - инструменты в заказе
- toolName - название инструмента
- toolNumber - идентификатор инструмента;
- createdAt - дата создания аккаунта;
- editedAt - дата последнего изменения аккаунта;
- _id - уникальный идентификатор инструмента;
- name - название инструмента;
- dailyprice - цена аренды инструмента за день;
- images - список изображений инструмента в бинарном виде;
- features - ассоциативный массив характеристик инструмента;
- reviews - список отзывов о инструменте;
- reviewer - клиент, оставивший отзыв
- name - имя
- surname - фамилия
- phone - номер телефона
- rating - оставленная оценка
- text - содержание отзыва
- reviewer - клиент, оставивший отзыв
- rating - оценка инструмента;
- ordersNumber - количество заказов на инструмент;
- category - категория инструмента;
- type - тип инструмента;
- totalPrice - цена инструмента;
- description - описание инструмента;
- createdAt - дата добавления инструмента;
- condition - состояние инструмента (LESS_THAT_HUNDRED_USES, LESS_THAN_THOUSAND_USES, OLD);
- _id - уникальный идентификатор отзыва;
- tool - инструмент, на который оставлен отзыв;
- toolName - название инструмента
- toolId - идентификатор инструмента
- reviewer - пользователь, оставивший отзыв;
- name - имя
- surname - фамилия
- phone - номер телефона
- rating - оценка инструмента;
- date - дата отзыва;
- text - текст отзыва;
Коллекция client. Пусть на одного клиента приходится 5 заказов (в том числе неактивных). Тогда, для хранения x клиентов понадобится:
- _id - ObjectID V = 12 байт
- name - String V = 15 байт
- surname - String V = 15 байт
- email - String V = 30 байт
- password - String V = 12 байт
- orders - Array V = 12*5 = 60 байт
- phone - String V = 12 байт
- image - Binary Data (предположим, что средний размер изображения составляет 500 Кб) V = 500000 байт
- createdAt - Date V = 8 байт
- editedAt - Date V = 8 байт
$$ 2x(12 + 60 + 8 + 8 + 8 + 36 + 12 + 12 + 12 + 12) = 360x $$
- _id - ObjectID V = 12 байт
- tools - Array V = 3*(12 + 8) = 60 байт
- startLeasing - Date V = 8 байт
- endLeasing - Date V = 8 байт
- price - Double V = 8 байт
- client - Object V = (12+12+12) = 36 байт
- deliveryType - String V = 12 байт
- deliveryState - String V = 12 байт
- paymentType - String V = 12 байт
- paymentState - String V = 12 байт
- _id - ObjectID V = 12 байт
- name - String V = 15 байт
- surname - String V = 15 байт
- email - String V = 15 байт
- phone - String V = 15 байт
- jobTitle - String V = 15 байт
- state - String V = 15 байт
- date - Date V = 8 байт
- orders - Array V = 5*(8+2*(12 + 8)) = 240 байт
- createdAt - Date V = 8 байт
- editedAt - Date V = 8 байт
Коллекция tool. Допустим, что у каждого инструмента есть 3 характеристики, 5 картинок и 50 отзывов, а всего существует 100 инструментов. Тогда:
- _id - ObjectID V = 12 байт
- dailyPrice - Double V = 8 байт
- images - Array (предположим, что средний размер изображения составляет 50 Кб) V = 5*50000 = 250000 байт
- features - Array V = 12*3 = 36 байт
- reviews - Array V = 50 * ((12+12+12) + 8 + 24) = 3400 байт
- rating - Double V = 8 байт
- category - String V = 12 байт
- type - String V = 12 байт
- createdAt - Date V = 8 байт
- totalPrice - Double V = 8 байт
- condition - String V = 12 байт
- _id - ObjectID V = 12 байт
- tool - Object V = 12 + 8 = 20 байт
- reviewer - Object V = 12 + 12 + 12 = 36 байт
- rating - Double V = 8 байт
- date - Date V = 8 байт
- text - String V = 100 байт
Для грубой оценки:
В БД у клиентов может не быть картинки (пусть в среднем у 1 из 2 клиентов будет картинка, тогда средний размер будет равен половине от изначального). Тогда получаем:
Отношение между фактическим и "чистым" объемом (отбросив свободный член) равно
Выразим объём БД через количество клиентов x: $$ V(x) = 500596x + 250090600 $$ Виден линейный рост зависимости объёма базы данных от количества клиентов.
- регистрация нового клиента
db.client.insert({
_id: ObjectId(),
name: "Иван",
surname: "Иванов",
email: "[email protected]",
password: "password",
orders: [],
phone: "+79123456789",
image: "someBinaryData"
})
- поиск аккаунта для входа в систему
db.client.find({
email: "[email protected]",
password: "password"
})
- поиск предстоящих заказов для определенного клиента
db.order.find({
"client.name": "Иван",
"client.surname": "Иванов",
endLeasing: { $gt: new Date() }
})
- просмотр всех инструментов
db.tool.find({})
- создание нового заказа
db.order.insert({
_id: ObjectId(),
tools: [
{ toolName: "Дрель", toolNumber: ObjectId("60725a34e8b57c4b3c2d9f12") },
{ toolName: "Перфоратор", toolNumber: ObjectId("60725a34e8b57c4b3c2d9f13") }
],
startLeasing: new Date(),
endLeasing: new Date(new Date().getTime() + 3 * 24 * 60 * 60 * 1000),
price: 100,
client: {
name: "Иван",
surname: "Иванов",
phone: "1234567890"
},
deliveryType: "courier",
deliveryState: "pending",
paymentType: "credit card",
paymentState: "unpaid",
createOrderTime: new Date(),
relatedWorker: {
name: "Анна",
surname: "Сидорова",
phone: "0987654321"
}
})
- Вычисление и обновление рейтингов инструмента
db.tool.find().forEach(function(tool) {
var totalRating = 0;
var reviewCount = 0;
db.review.find({ toolId: tool._id }).forEach(function(review) {
totalRating += review.rating;
reviewCount++;
});
if (reviewCount > 0) {
var newRating = totalRating / reviewCount;
db.tool.update(
{ _id: tool._id },
{ $set: { rating: newRating } }
);
}
});
- Поиск всех инструментов, которые еще не вернули
db.order.find({
endLeasing: { $gt: new Date() }
}).forEach(function(order) {
order.tools.forEach(function(tool) {
printjson(tool);
});
});
- поиск самых популярных инструментов
db.tool.aggregate([
{ $sort: { ordersNumber: -1 } },
{ $limit: 10 } // 10 самых популярных инструментов
]).forEach(function(tool) {
printjson(tool);
});
Разница от нереляционной версии:
- наличие отдельной таблицы feature для хранения характеристик инструментов
- наличие таблицы order_tool для реализации связи между таблицами order и tool
Поля и типы данных полей идентичны.
Пусть x - количество клиентов, тогда:
- _id - INT V = 8 байт
- name - VARCHAR V = 15 байт
- surname - VARCHAR V = 15 байт
- email - VARCHAR V = 30 байт
- password - VARCHAR V = 12 байт
- contact - VARCHAR V = 12 байт
- image - BinaryData V = 500000 байт
- createdAt - Date V = 8 байт
- editedAt - Date V = 8 байт
Пусть у каждого клиента будет 2 заказа. Тогда
$$ V(x) = 2x(8+8+...) = 184x $$
- _id - INT V = 8 байт
- startLeasing - Date V = 8 байт
- endLeasing - Date V = 8 байт
- price - Double V = 8 байт
- clientId - INT V = 8 байт
- deliveryType - VARCHAR V = 12 байт
- deliveryState - VARCHAR V = 12 байт
- paymentType - VARCHAR V = 12 байт
- paymentState - VARCHAR V = 12 байт
- workerId - INT = V = 8 байт
Пусть в каждом заказе будет 3 инструмента. Так как у каждого клиента по 2 заказа, то
$$ V(x) = 2316*x = 96x $$
- orderId - INT = 8 байт
- toolId - INT = 8 байт
Пусть у каждого инструмента есть 3 характеристики, 5 картинок и 50 отзывов, а всего существует 100 инструментов. Тогда: $$ V(x) = 100*(8+8+250000+8+12+12+8+8+12) = 25007600 $$
- _id - INT V = 8 байт
- dailyPrice - Double V = 8 байт
- images - Array (предположим, что средний размер изображения составляет 50 Кб) V = 5*50000 = 250000 байт
- rating - Double V = 8 байт
- category - VARCHAR V = 12 байт
- type - VARCHAR V = 12 байт
- createdAt - Date V = 8 байт
- totalPrice - Double V = 8 байт
- condition - String V = 12 байт
Пусть на каждого работника приходится 10 клиентов. Тогда:
- _id - INT V = 8 байт
- name - VARCHAR V = 12 байт
- surname - VARCHAR V = 12 байт
- email - VARCHAR V = 12 байт
- phone - VARCHAR V = 12 байт
- jobTitle - VARCHAR V = 12 байт
- state - VARCHAR V = 12 байт
- date - Date V = 8 байт
- createdAt - Date V = 8 байт
- editedAt - Date V = 8 байт
- _id - INT V = 8 байт
- toolId - INT V = 8 байт
- text - VARCHAR V = 12 байт
- _id - INT V = 8 байт
- toolId - INT V = 8 байт
- reviewerId - INT V = 8 байт
- text - VARCHAR V = 12 байт
- rating - INT V = 8 байт
- date - Date V = 8 байт
Тогда получаем общий объём: $$ V(x) = 10x + 96x + 184x + 500108x + 8400 + 260000 + 25004800 + 90 = 500398x + 25273290 $$
В БД у клиентов может не быть картинки (пусть в среднем у 1 из 2 клиентов будет картинка, тогда средний размер будет равен половине от изначального). Тогда получаем:
Отношение между фактическим и "чистым" объемом (отбросив свободный член) равно
Объём имеет линейный рост в зависимости от количества клиентов.
Таблица client
_id | name | surname | password | contact | image | |
---|---|---|---|---|---|---|
1 | Артём | Палец | [email protected] | pass123 | 123-456-7890 | [binary data] |
2 | Иван | Смелый | [email protected] | pass456 | 987-654-3210 | [binary data] |
Таблица order
_id | startLeasing | endLeasing | price | clientId | deliveryType | deliveryState | paymentType | paymentState | workerId |
---|---|---|---|---|---|---|---|---|---|
1 | 2023-01-01 | 2023-01-10 | 100.0 | 1 | Standard | Delivered | CreditCard | Paid | 1 |
2 | 2023-02-01 | 2023-02-10 | 150.0 | 2 | Express | InProgress | PayPal | Pending | 2 |
Таблица order_tool
orderId | toolId |
---|---|
1 | 1 |
1 | 2 |
1 | 3 |
2 | 1 |
2 | 2 |
2 | 4 |
Таблица tool
_id | dailyPrice | images | rating | category | type |
---|---|---|---|---|---|
1 | 10.0 | [binary data] | 4.5 | Drill | Electric |
2 | 15.0 | [binary data] | 4.0 | Saw | Manual |
Таблица worker
_id | name | surname | phone | jobTitle | state | date | |
---|---|---|---|---|---|---|---|
1 | Алиса | Иванова | [email protected] | 555-123-4567 | Manager | Active | 2023-01-01 |
2 | Олег | Иванов | [email protected] | 555-987-6543 | Worker | Active | 2023-02-01 |
Таблица feature
_id | toolId | text |
---|---|---|
1 | 1 | High power |
2 | 1 | Lightweight |
3 | 2 | Durable |
Таблица review
_id | toolId | reviewerId | text | rating | date |
---|---|---|---|---|---|
1 | 1 | 1 | Great tool! | 5 | 2023-01-02 |
2 | 1 | 2 | Works well. | 4 | 2023-01-03 |
3 | 2 | 1 | Good for the price. | 3 | 2023-01-04 |
- регистрация нового клиента
INSERT INTO client (_id, name, surname, email, password, phone, image)
VALUES (NULL, 'Иван', 'Иванов', '[email protected]', 'password', '+79123456789', 'someBinaryData');
- поиск аккаунта для входа в систему
SELECT * FROM client
WHERE email = '[email protected]' AND password = 'password';
- поиск предстоящих заказов для определенного клиента
SELECT * FROM orders
WHERE clientId = (SELECT _id FROM client WHERE name = 'Иван' AND surname = 'Иванов')
AND endLeasing > CURRENT_DATE;
- просмотр всех инструментов
SELECT * FROM tool;
- создание нового заказа
INSERT INTO orders (_id, startLeasing, endLeasing, price, clientId, deliveryType, deliveryState, paymentType, paymentState, createOrderTime, relatedWorkerId)
VALUES (NULL, CURRENT_DATE, DATE_ADD(CURRENT_DATE, INTERVAL 3 DAY), 100, (SELECT _id FROM client WHERE name = 'Иван' AND surname = 'Иванов'), 'courier', 'pending', 'credit card', 'unpaid', CURRENT_DATE, (SELECT _id FROM worker WHERE name = 'Анна' AND surname = 'Сидорова'));
INSERT INTO order_tool (orderId, toolId)
VALUES (LAST_INSERT_ID(), GET_TOOL_ID('Дрель'));
INSERT INTO order_tool (orderId, toolId)
VALUES (LAST_INSERT_ID(), GET_TOOL_ID('Перфоратор'));
- NoSQL требует больше памяти, по сравнению с SQL, так в нем дублируются некоторые данные. SQL выигрывает по памяти, так как вместо того, чтобы хранить сами объекты целиком (как NoSQL), он хранит только id определенного элемента из другой таблицы.
- По удобству запросов выигрывает NoSQL, так как ввиду дублирования данных в некоторых сущностях, нам не приходится JOIN-ить с другими коллекциями. Для некоторых запросов SQL приходится JOIN-ить несколько таблиц, что может сказать в скорости доступа.
NoSQL требует больше памяти, но удобен и быстр в запросах, в то время как SQL требует меньше памяти и не совсем удобен в запросах, из-за того что приходится JOIN-ить таблицы. Для данной задачи NoSQL подходит лучше, чем SQL.