Skip to content

Модель данных

Сулименко Максим edited this page Dec 5, 2024 · 24 revisions

Реляционная модель

PostgreSQL

Реляционная модель

1. user_account

Назначение: хранение базовой информации о всех пользователях системы (пользователи, администраторы).

id INT AUTO_INCREMENT PRIMARY KEY (4 байта)
username VARCHAR(50) NOT NULL (50 байт)
password_hash VARCHAR(255) NOT NULL (255 байт)
email VARCHAR(255) NOT NULL (255 байт)
permissions ENUM('regular', 'administrator') DEFAULT 'regular' (1 байт)
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP (4 байта)
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP (4 байта)
last_login_at TIMESTAMP NULL (4 байта)

2. payment

Назначение: хранение информации об оплате доступа пользователями.

id INT AUTO_INCREMENT PRIMARY KEY (4 байта)
user_id INT NOT NULL (4 байта)
job_id INT NULL (4 байта) -- Связь с конкретной задачей (добавлено)
amount DECIMAL(10,2) NOT NULL (5 байт)
payment_method VARCHAR(50) NOT NULL (50 байт)
payment_status VARCHAR(50) NOT NULL (50 байт)
transaction_id VARCHAR(100) NULL (100 байт)
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP (4 байта)
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP (4 байта)

3. job

Назначение: хранение информации о задачах на транскрибацию.

id INT AUTO_INCREMENT PRIMARY KEY (4 байта)
user_id INT NOT NULL (4 байта)
title VARCHAR(255) NOT NULL (255 байт)
status VARCHAR(50) NOT NULL (50 байт)
source_language VARCHAR(50) NOT NULL (50 байт)
file_format VARCHAR(50) NOT NULL (50 байт)
description TEXT NULL (средний размер 1000 байт)
input_file_path VARCHAR(255) NOT NULL (255 байт)
output_file_path VARCHAR(255) NULL (255 байт)
estimated_finish_datetime TIMESTAMP NULL (4 байта) -- Добавлено поле
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP (4 байта)
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP (4 байта)
host_id INT NULL (4 байта)
error_message VARCHAR(255) NULL (255 байт)

4. host

Назначение: хранение информации о серверах для транскрибации.

id INT AUTO_INCREMENT PRIMARY KEY (4 байта)
hostname VARCHAR(255) NOT NULL (255 байт)
address VARCHAR(255) NOT NULL (255 байт)
description VARCHAR(255) NULL (255 байт)
status VARCHAR(50) NOT NULL (50 байт)
cpu_info VARCHAR(255) NULL (255 байт) -- Информация о CPU (добавлено)
gpu_info VARCHAR(255) NULL (255 байт) -- Информация о GPU (добавлено)
ram_size_gb INT NULL (4 байта)        -- Объем RAM в ГБ (добавлено)
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP (4 байта)
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP (4 байта)

Оценка удельного объема информации:

  1. user_account:
id: 4 байта
username: 50 байт
password_hash: 255 байт
email: 255 байт
permissions: 1 байт
created_at: 4 байта
updated_at: 4 байта
last_login_at: 4 байта
-----------------------------
Итого: 577 байт на запись
  1. payment:
id: 4 байта
user_id: 4 байта
job_id: 4 байта (добавлено)
amount: 5 байт
payment_method: 50 байт
payment_status: 50 байт
transaction_id: 100 байт
created_at: 4 байта
updated_at: 4 байта
-----------------------------
Итого: 225 байт на запись
  1. job:
id: 4 байта
user_id: 4 байта
title: 255 байт
status: 50 байт
source_language: 50 байт
file_format: 50 байт
description: 1000 байт
input_file_path: 255 байт
output_file_path: 255 байт
estimated_finish_datetime: 4 байта (добавлено)
created_at: 4 байта
updated_at: 4 байта
host_id: 4 байта
error_message: 255 байт
-----------------------------
Итого: 2194 байт на запись
  1. host:
id: 4 байта
hostname: 255 байт
address: 255 байт
description: 255 байт
status: 50 байт
cpu_info: 255 байт (добавлено)
gpu_info: 255 байт (добавлено)
ram_size_gb: 4 байта (добавлено)
created_at: 4 байта
updated_at: 4 байта
-----------------------------
Итого: 1341 байт на запись

Оценка общего объема данных:

Предположения:

  • Количество пользователей: U
  • Средний пользователь имеет 5 задач (job)
  • Количество платежей на пользователя: 1
  • Количество хостов: H = 10

Расчёт общего объёма данных $V(U)$:

  • user_account: 577 байт * U
  • payment: 225 байт * U
  • job: 2194 байт * (5 * U) = 10,970U байт
  • host: 1341 байт * 10 = 13,410 байт

Суммарный объём данных:

V(U) = (577U) + (225U) + (10,970U) + 13,410
V(U) = (11,772U) + 13,410 байт

Пример расчёта для 1000 пользователей (U = 1000):

V(1000) = 11,772 * 1000 + 13,410 = 11,772,000 + 13,410 = 11,785,410 байт ≈ 11.79 МБ

Избыточность данных:

Избыточными данными в нашей базе данных являются синтетические идентификаторы (первичные ключи) и внешние ключи, определяющие связи между сущностями.

Список избыточных полей:

  1. user_account
  • id (4 байта)
  1. payment
  • id (4 байта)
  • user_id (4 байта)
  1. job
  • id (4 байта)
  • user_id (4 байта)
  • host_id (4 байта)
  1. host
  • id (4 байта)

Всего избыточных полей: 10. Каждое занимает 4 байта.

Общий объём избыточных данных:

  1. user_account: id
  • 4 байта * U = 4U байт
  1. payment: id, user_id
  • (4 + 4) байта * U = 8U байт
  1. job: id, user_id, host_id
  • (4 + 4 + 4) байта * (5U) = 12 * 5U = 60U байт
  1. host: id
  • 4 байта * 10 = 40 байт
Общий объём = 4U + 8U + 60U + 40 = (72U + 40) байт

Примеры данных

1. user_account

id username password_hash email permissions created_at updated_at last_login_at
1 john_doe hashed_password1 [email protected] regular 2024-01-01 09:00:00 2024-01-01 09:00:00 2024-01-01 09:00:00
2 jane_smith hashed_password2 [email protected] regular 2024-01-02 10:00:00 2024-01-02 10:00:00 2024-01-02 10:00:00
3 admin_user hashed_password3 [email protected] administrator 2024-01-03 11:00:00 2024-01-03 11:00:00 2024-01-03 11:00:00

2. payment

id user_id job_id amount payment_method payment_status transaction_id created_at updated_at
1 1 1 29.99 Credit Card completed TXN001 2024-01-02 14:20:00 2024-01-02 14:20:00
2 2 2 49.99 PayPal completed TXN002 2024-01-03 10:05:00 2024-01-03 10:05:00
3 1 NULL 19.99 Credit Card pending TXN003 2024-01-04 16:45:00 2024-01-04 16:45:00

3. job

id user_id title status source_language file_format description input_file_path output_file_path estimated_finish_datetime created_at updated_at host_id error_message
1 1 Meeting Notes pending English mp3 Transcribe meeting /uploads/jobs/1/meeting_notes.mp3 NULL 2024-01-03 18:30:00 2024-01-03 16:30:00 2024-01-03 16:30:00 NULL NULL
2 2 Lecture Video processing Spanish mp4 Transcribe lecture /uploads/jobs/2/lecture_video.mp4 NULL 2024-01-04 12:00:00 2024-01-04 09:00:00 2024-01-04 09:15:00 2 NULL
3 1 Podcast Episode completed French mp3 Transcribe podcast /uploads/jobs/3/podcast_episode.mp3 /results/jobs/3/output.txt NULL 2024-01-05 11:00:00 2024-01-05 12:30:00 1 NULL

4. host

id hostname address description status cpu_info gpu_info ram_size_gb created_at updated_at
1 transcriber01 192.168.0.101 Primary Transcription Host active Intel Xeon NVIDIA Tesla V100 128 2024-01-01 08:00:00 2024-01-02 12:00:00
2 transcriber02 192.168.0.102 Secondary Transcription Host active AMD EPYC NVIDIA Tesla P100 64 2024-01-01 08:10:00 2024-01-03 15:30:00
3 transcriber03 192.168.0.103 Backup Host inactive Intel Core i9 None 32 2024-01-01 08:20:00 2024-01-04 10:00:00

Примеры запросов

1. Сценарий использования: Регистрация

INSERT INTO user_account (username, password_hash, email)
VALUES ('new_user', 'hashed_password', '[email protected]');

2. Сценарий использования: Создание платежа

INSERT INTO payment (user_id, amount, payment_method, payment_status, transaction_id)
VALUES (1, 49.99, 'Credit Card', 'pending', 'TXN004');

3. Сценарий использования: Редактирование данных профиля

UPDATE user_account
SET email = '[email protected]', updated_at = CURRENT_TIMESTAMP
WHERE id = 1;

4. Сценарий использования: Создание новой задачи

INSERT INTO job (user_id, title, status, source_language, file_format, description, input_file_path)
VALUES (1, 'Interview Recording', 'pending', 'English', 'wav', 'Transcribe interview', '/uploads/jobs/4/interview.wav');

Получение id созданной задачи:

SELECT LAST_INSERT_ID() AS job_id;

5. Сценарий использования: Поиск по задачам

SELECT id, title, status, created_at
FROM job
WHERE user_id = 1 AND status = 'completed'
ORDER BY created_at DESC;

6. Сценарий использования: Управление статусом задачи

UPDATE job
SET status = 'processing', host_id = 2, updated_at = CURRENT_TIMESTAMP
WHERE id = 4;

7. Сценарий использования: Управление серверами

Задача: Добавление нового хоста.

INSERT INTO host (hostname, address, description, status)
VALUES ('transcriber04', '192.168.0.104', 'Additional Host', 'active');

Задача: Обновление статуса сервера.

UPDATE host
SET status = 'inactive', updated_at = CURRENT_TIMESTAMP
WHERE id = 3;

8. Сценарий использования: Получение статистики

SELECT status, COUNT(*) AS job_count
FROM job
GROUP BY status;

9. Сценарий использования: Массовый экспорт данных

SELECT *
FROM user_account
INTO OUTFILE '/path/to/user_account.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n';

10. Поиск самых загруженных / простаивающих серверов

SELECT h.id, h.hostname, h.status, h.cpu_info, h.gpu_info, h.ram_size_gb, COUNT(j.id) AS active_jobs
FROM host h
LEFT JOIN job j ON h.id = j.host_id AND j.status = 'processing'
GROUP BY h.id, h.hostname, h.status, h.cpu_info, h.gpu_info, h.ram_size_gb
ORDER BY active_jobs DESC;

11. Пользователи-должники

SELECT ua.id, ua.username, ua.email, SUM(p.amount) AS total_pending_amount
FROM user_account ua
JOIN payment p ON ua.id = p.user_id
WHERE p.payment_status = 'pending'
GROUP BY ua.id, ua.username, ua.email
HAVING total_pending_amount > 0;

12. Поиск видео-дубликатов по названию или пути к файлу

  • Поиск дубликатов по названию:
SELECT title, COUNT(*) AS occurrences
FROM job
GROUP BY title
HAVING COUNT(*) > 1;
  • Получение деталей дубликатов по названию:
SELECT j.*
FROM job j
JOIN (
    SELECT title
    FROM job
    GROUP BY title
    HAVING COUNT(*) > 1
) dup ON j.title = dup.title
ORDER BY j.title;
  • Поиск дубликатов по пути к файлу:
SELECT input_file_path, COUNT(*) AS occurrences
FROM job
GROUP BY input_file_path
HAVING COUNT(*) > 1;
  • Получение деталей дубликатов по пути к файлу:
SELECT j.*
FROM job j
JOIN (
    SELECT input_file_path
    FROM job
    GROUP BY input_file_path
    HAVING COUNT(*) > 1
) dup ON j.input_file_path = dup.input_file_path
ORDER BY j.input_file_path;

Нереляционная модель

MongoDB

1. users

{
  "_id": ObjectId(),
  "username": "string",
  "email": "string",
  "password_hash": "string"
  "permissions": "string",
  "created_at": ISODate(),
  "updated_at": ISODate(),
  "last_login_at": ISODate(),
  "payments": [
    {
      "_id": ObjectId(),
      "price": "string",
      "payment_method": "string",
      "payment_status": "string",
      "created_at": ISODate(),
      "updated_at": ISODate(),
      "job_id": ObjectId() -- Связь с конкретной задачей (добавлено)

    }
  ],
  "jobs":[ObjectId()]
}

2. jobs

{ 
    "_id": "ObjectId()",      
    "user_id": "ObjectId()",      
    "title": "string",           
    "status": "string",          
    "source_language": "string",  
    "file_format": "string",    
    "description": "string", 
    "input_file": "string", 
    "output_file": "string", 
    "created_at": ISODate(), 
    "updated_at": ISODate(), 
    "host_id": "ObjectId()",
    "estimated_finish_datetime": ISODate() -- Примерное время выполнения(добавлено)
 }

3. servers

{ 
  "_id": "ObjectId()",             
  "hostname": "string",             
  "address": "string",        
  "description": "string",          
  "status": "string",               
  "created_at": ISODate(),             
  "updated_at": ISODate(),
  "cpu_info": "string" -- Информация о CPU (добавлено)
  "gpu_info": "string" -- Информация о GPU (добавлено)
  "ram_size_gb": "Int32" -- Объем RAM в ГБ (добавлено)   
  "current_tasks": [       
    "ObjectId()" 
  ], 
  "completed_tasks": [ 
    "ObjectId()" 
  ]             
}

Оценка удельного объема информации

Средний размер одного документа коллекции

Предположительно, пользователь будет:

  • создавать в среднем 10 задач
  • совершать в среднем 4 покупки

Предположительно, будет 1 сервер на 10 пользователей.

1. users

  • _id: 12 байт
  • username: 500 байт
  • email: 500 байт
  • password_hash: 500 байт
  • permissions: 500 байт
  • created_at: 8 байт
  • updated_at: 8 байт
  • last_login_at: 8 байт
  • payments: зависит от количества, по 1528 на каждую
  • jobs: зависит от количества, по 12 на каждую

Итого для одного пользователя: 12 + 500 + 500 + 500 + 500 + 8 + 8 + 8 + 2 * 1540 + 10 * 12 = 5236 байт

Для оплаты количество байт получается следующим образом:

  • _id: 12 байт
  • price: 500 байт
  • payment_method: 500 байт
  • payment_status: 500 байт
  • created_at: 8 байт
  • updated_at: 8 байт
  • job_id: 12 байт

Итого для одной оплаты: 12 + 500 + 500 + 500 + 8 + 8 + 12 = 1540 байт

2. jobs

  • _id: 12 байт
  • user_id: 12 байт
  • title: 500 байт
  • status: 500 байт
  • source_language: 500 байт
  • file_format: 500 байт
  • description: 500 байт
  • input_file: 500 байт
  • output_file: 500 байт
  • created_at: 8 байт
  • updated_at: 8 байт
  • host_id: 12 байт
  • estimated_finish_datetime: 8 байт (добавлено)

Итого для одной задачи: 12 + 12 + 500 + 500 + 500 + 500 + 500 + 500 + 500 + 8 + 8 + 12 = 3560 байт

3. servers

  • _id: 12 байт
  • hostname: 500 байт
  • address: 500 байт
  • description: 500 байт
  • status: 500 байт
  • created_at: 8 байт
  • updated_at: 8 байт
  • current_tasks: зависит от количества, по 12 на каждую
  • completed_tasks: зависит от количества, по 12 на каждую
  • cpu_info: 20 байт -- Информация о CPU (добавлено)
  • gpu_info: 20 байт -- Информация о GPU (добавлено)
  • ram_size_gb: 4 байта -- Объем RAM в ГБ (добавлено)

Итого для одного сервера: 12 + 500 + 500 + 500 + 500 + 8 + 8 + 10 * 10 * 12 + 20 + 20 + 4 = 3272 байт

При количестве пользователей равным u:

V ( u ) = ( 5236 + 3560 ∗ 10 + 3272 / 10 ) ∗ u = 41193.2 ∗ u

Избыточность данных

Объем данных в коллекциях без дублирования:

Сервер:

  • 100 задач в среднем на сервер → данные хранятся как в коллекции server (в массивах current_tasks и completed_tasks), так и в коллекции jobs.

Пользователь:

  • 10 задач в среднем на пользователя → данные хранятся как в коллекции users (в массиве jobs), так и в коллекции jobs.
  • 2 оплаты на пользователя → создаются записи в массиве payments, без дублирования.

Избыточность по задачам:

Одна задача занимает 3560 байт в коллекции jobs и по 12 байт (ссылки на задачу) в массивах пользователя и сервера. В этом случае объем дублирования минимален, но все равно присутствует.

Для 100 задач - (3560 + 2 * 12) * 100 = 358400 байт.

Объем без дублирования:

  • Основные данные сервера - 2036 байт (основные поля)
  • Основные данные 10 пользователей - 20280 байт (основные поля)
  • Объем на 20 платежей - 30560 байт
  • Объем на 100 задач - 355200 байт

Итого без дублирования - 380572 байт

Объем с дублированием

  • Объем на 1 сервер - 3228 байт (с 100 задачами)
  • Объем на 10 пользователей - 21560 байт (с 100 задачами)
  • Объем на 20 платежей - 30560 байт
  • Объем на 100 задач - 355200 байт

Итого с дублированием - 410548 байт

Избыточность

V ( u ) / V c l e a n ( u ) = 410548 ∗ u / 380572 ∗ u ≈ 1.0787

Направление роста модели

  • Основные данные пользователей увеличиваются пропорционально количеству пользователей и серверов.
  • Однако, каждый новый пользователь приносит с собой дублированные данные по платежам и задачам, что ведет к росту общего объема информации быстрее, чем линейный рост объема полезных данных.
  • Данные о задачах дублируются в трёх местах: в коллекции jobs и в полях внутри пользователей и серверов.
  • По мере добавления новых задач на каждого пользователя, объем дублированной информации будет расти. При росте средней карточки растений с 10 до 20, например, избыточность увеличится пропорционально этому количеству.
  • С каждым новым пользователем и задачей будет расти количество дублированной информации между соответствующими коллекциями.
  • Если число задач в среднем на пользователя увеличится, это также увеличит избыточность модели.
  • Данные о платежах не дублируются, но их объем будет линейно расти по мере добавления новых платежей.
  • Избыточность в этой модели будет увеличиваться с ростом базы данных, так как с каждым новым пользователем и его задачами количество дублированной информации возрастает.
  • При увеличении числа объектов в коллекции jobs, доля дублированных данных растет, что приводит к увеличению общего объема информации без эквивалентного увеличения полезных данных.

Модель имеет экспоненциальное направление роста избыточности по мере увеличения количества пользователей, задач и серверов

Примеры данных

1. users

image

{
  "_id": {
    "$oid": "6721e2a5811ed426d01984d4"
  },
  "username": "john_doe",
  "email": "[email protected]",
  "password_hash": "hashed_password",
  "permissions": "user",
  "created_at": {
    "$date": "2024-10-30T00:00:00.000Z"
  },
  "updated_at": {
    "$date": "2024-10-30T00:00:00.000Z"
  },
  "last_login_at": {
    "$date": "2024-10-30T00:00:00.000Z"
  },
  "payments": [
    {
      "price": "100",
      "payment_method": "credit_card",
      "payment_status": "completed",
      "created_at": {
        "$date": "2024-10-30T00:00:00.000Z"
      },
      "updated_at": {
        "$date": "2024-10-30T00:00:00.000Z"
      },
      "job_id": {
        "$oid": "6721e3a5811ed426d01984d5"
      }
    }
  ],
  "jobs": []
}

2. jobs

image

{
  "_id": {
    "$oid": "6721e478811ed426d01984dd"
  },
  "user_id": {
    "$oid": "6721e3da811ed426d01984dc"
  },
  "title": "Translation Job 1",
  "status": "processing",
  "source_language": "en",
  "file_format": "mp3",
  "description": "Transcribe meeting",
  "input_file": "/uploads/jobs/1/meeting_notes.mp3",
  "output_file": "NULL",
  "created_at": {
    "$date": "2024-10-30T00:00:00.000Z"
  },
  "updated_at": {
    "$date": "2024-10-30T00:00:00.000Z"
  },
  "host_id": {
    "$oid": "3521e3da811ed426d01984dc"
  },
  "estimated_finish_datetime":{
    "$date": "2024-10-30T00:00:00.000Z"
  }
}

{
  "_id": {
    "$oid": "6721e5f5811ed426d01984e5"
  },
  "user_id": {
    "$oid": "6721e5a1811ed426d01984e4"
  },
  "title": "Lecture Video",
  "status": "processing",
  "source_language": "Spanish",
  "file_format": "mp4",
  "description": "Transcribe lecture",
  "input_file": "/uploads/jobs/2/lecture_video.mp4",
  "output_file": "NULL",
  "created_at": {
    "$date": "2024-10-30T00:00:00.000Z"
  },
  "updated_at": {
    "$date": "2024-10-30T00:00:00.000Z"
  },
  "host_id": {
    "$oid": "4912e5a1811ed426d01984e4"
  },
  "estimated_finish_datetime":{
    "$date": "2024-10-30T00:00:00.000Z"
  }
}

3. servers

image

{
  "_id": {
    "$oid": "6721e390811ed426d01984d9"
  },
  "hostname": "server1",
  "address": "192.168.1.1",
  "description": "Primary server",
  "status": "active",
  "created_at": {
    "$date": "2024-10-30T00:00:00.000Z"
  },
  "updated_at": {
    "$date": "2024-10-30T00:00:00.000Z"
  },
  "current_tasks": [
    {
      "$oid": "64a8f6a9b3b7e3629f09abcd"
    }
  ],
  "completed_tasks": [
    {
      "$oid": "64a8f6a9b3b7e3629f09abef"
    }
  ],
  "cpu_info": "Intel Xeon E5-2690 v4",
  "gpu_info": "NVIDIA Tesla K80",
  "ram_size_gb": 128
}

{
  "_id": {
    "$oid": "6721e594811ed426d01984e1"
  },
  "hostname": "server2",
  "address": "192.168.1.2",
  "description": "Secondary Transcription server",
  "status": "active",
  "created_at": {
    "$date": "2024-10-30T00:00:00.000Z"
  },
  "updated_at": {
    "$date": "2024-10-30T00:00:00.000Z"
  },
  "current_tasks": [
    {
      "$oid": "3412e3da811ed426d0198445"
    }
  ],
  "completed_tasks": [
    {
      "$oid": "9081e3da811ed426d0198445"
    }
  ],
  "cpu_info": "AMD EPYC 7742",
  "gpu_info": "NVIDIA A100",
  "ram_size_gb": 256
}

Примеры запросов

1. Сценарий использования: Регистрация

user_data = {
    "username": "new_user",
    "password_hash": "hashed_password",
    "email": "[email protected]",
    "permissions": "user",
    "created_at": datetime.utcnow(),
    "updated_at": datetime.utcnow(),
    "last_login_at": None,
    "payments": [],
    "jobs": []
}
user_id = db.user.insert_one(user_data).inserted_id

2. Сценарий использования: Создание платежа

payment_data = {
    "price": "49.99",
    "payment_method": "Credit Card",
    "payment_status": "pending",
    "job_id": ObjectId("64a8f6a9b3b7e3629f09abcd"),
    "created_at": datetime.utcnow(),
    "updated_at": datetime.utcnow()
}
db.user.update_one({"_id": user_id}, {"$push": {"payments": payment_data}})

3. Сценарий использования: Редактирование данных профиля

db.user.update_one(
    {"_id": user_id},
    {
        "$set": {
            "email": "[email protected]",
            "updated_at": datetime.utcnow()
        }
    }
)

4. Сценарий использования: Создание новой задачи

job_data = {
    "user_id": user_id,
    "title": "Interview Recording",
    "status": "pending",
    "source_language": "English",
    "file_format": "wav",
    "description": "Transcribe interview",
    "input_file": "/uploads/jobs/4/interview.wav",
    "created_at": datetime.utcnow(),
    "updated_at": datetime.utcnow(),
    "host_id": None
}
job_id = db.job.insert_one(job_data).inserted_id

5. Сценарий использования: Поиск по задачам

completed_jobs = db.job.find(
    {"user_id": user_id, "status": "completed"},
    {"_id": 1, "title": 1, "status": 1, "created_at": 1}
).sort("created_at", -1)

6. Сценарий использования: Управление статусом задачи

db.job.update_one(
    {"_id": job_id},
    {
        "$set": {
            "status": "processing",
            "host_id": "3",
            "updated_at": datetime.utcnow()
        }
    }
)

7. Сценарий использования: Управление серверами

Задача: Добавление нового хоста.

host_data = {
    "hostname": "transcriber04",
    "address": "192.168.0.104",
    "description": "Additional Host",
    "status": "active",
    "created_at": datetime.utcnow(),
    "updated_at": datetime.utcnow(),
    "current_tasks": [],
    "completed_tasks": [],
    "cpu_info": "Intel Xeon Platinum 8358P",
    "gpu_info": "NVIDIA A100",
    "ram_size_gb": 512
}
host_id = db.server.insert_one(host_data).inserted_id

Задача: Обновление статуса сервера.

db.server.update_one(
    {"_id": host_id},
    {
        "$set": {
            "status": "inactive",
            "updated_at": datetime.utcnow()
        }
    }
)

8. Сценарий использования: Получение статистики

pipeline = [
    {"$group": {"_id": "$status", "job_count": {"$count": {}}}}
]
status_counts = db.job.aggregate(pipeline)

9. Сценарий использования: Массовый экспорт данных

with open("user_account.csv", "w", newline="") as file:
    writer = csv.writer(file)
    writer.writerow(["_id", "username", "email", "created_at"])

    for user in db.user.find({}, {"_id": 1, "username": 1, "email": 1, "created_at": 1}):
        writer.writerow([user["_id"], user["username"], user["email"], user["created_at"]])

Сравнение моделей

Удельный объем информации

Реляционная модель имеет меньший удельный объем информации, чем нереляционная. Связано это с тем, что в нереляционной модели необходимо дублировать хранение данных для обеспечения меньшего числа обращений к базе данных, в то время как в реляционной время уйдет на объединение разных таблиц в одну коллекцию данных.

Сравнения для моделей

  • Для модели Users NoSQL: 577 байт SQL: 5212 байт
  • Для модели Payments NoSQL: 1540 байт SQL: 221 байт
  • Для модели jobs NoSQL: 3560 байт SQL: 2190 байт
  • Для модели hosts NoSQL: 3272 байт SQL: 827 байт

Запросы по отдельным юзкейсам

Количество запросов в MongoDB не зависит от числа объектов в коллекции. В реляционной модели большее число объектов может потребовать дополнительные запросы из-за необходимости соединения данных.

  • Просмотр платежей/работ NoSQL: 1 SQL: 2
  • Создание платежа NoSQL: 1 SQL: 1
  • Авторизация/Регистрация NoSQL: 1 SQL: 1
  • Поиск информации по серверу NoSQL: 1 SQL: 1

Задействованные коллекции

  • Просмотр платежей/работ NoSQL: 1 SQL: 3
  • Создание платежа NoSQL: 1 SQL: 1
  • Авторизация/Регистрация NoSQL: 1 SQL: 1
  • Поиск информации по серверу NoSQL: 1 SQL: 1

Вывод

На основе приведённой выше оценки можно заключить следующее для данного проекта:

  • По удельному объему реляционная модель имеет меньший объем , чем нереляционная.
  • По количеству запросов к базе данных обе модели показывают приблизительно одинаковые результаты.
  • По числу используемых коллекций лучшее значение у нереляционной модели.
  • Несмотря на то, что MongoDB может облегчить некоторые задачи за счет меньшего количества запросов и поддержки встроенных функций, это также переносит больше ответственности на поддержание и управление бизнес-логикой на уровне базы данных, что в свою очередь может усложнить процесс разработки и масштабирования приложения.

Таким образом, SQL выглядит предпочтительнее для данного проекта, обеспечивая более эффективное использование ресурсов и упрощая поддержку приложения в долгосрочной перспективе.

Clone this wiki locally