Каким образом можно создать структуру базы данных для хранения истории заказов?

Как правильно реализовать систему учета истории заказов для фотостудии? Мы разработали схему базы данных (см. приложенное фото), но сталкиваемся с трудностями при работе с JSON в сущности "история заказа". Мы хотели бы убрать использование JSON и преобразовать атрибуты в более простые типы данных, такие как varchar2, number, boolean и другие. Основная цель истории заказов состоит в том, чтобы иметь возможность в любое время просматривать все обновления, связанные с заказами, включая изменения статуса. Как можно организовать структуру данных для этого?
  • 30 ноября 2024 г. 23:03
Ответы на вопрос 2
Чтобы создать эффективную структуру базы данных для хранения истории заказов фотостудии и убрать использование JSON, можно воспользоваться реляционной моделью. Давайте рассмотрим, как можно организовать таблицы и их взаимосвязи для учета истории заказов.

### Основные таблицы:

1. **Заказы (Orders)**:
   - `id` (primary key, number) - уникальный идентификатор заказа.
   - `client_id` (foreign key, number) - идентификатор клиента.
   - `created_at` (timestamp) - дата и время создания заказа.
   - `total_amount` (number) - общая сумма заказа.
   - `status` (varchar2) - текущий статус заказа (например, "Ожидание", "Выполнен", "Отменен").

2. **Клиенты (Clients)**:
   - `id` (primary key, number) - уникальный идентификатор клиента.
   - `name` (varchar2) - имя клиента.
   - `contact_info` (varchar2) - информация для связи.

3. **История заказов (OrderHistory)**:
   - `id` (primary key, number) - уникальный идентификатор записи в истории.
   - `order_id` (foreign key, number) - идентификатор заказа.
   - `status` (varchar2) - статус заказа на данный момент времени.
   - `changed_at` (timestamp) - дата и время изменения статуса.
   - `note` (varchar2) - дополнительная информация о смене статуса (необязательно).

### Пример структуры таблиц:

```sql
CREATE TABLE Clients (
    id NUMBER PRIMARY KEY,
    name VARCHAR2(255) NOT NULL,
    contact_info VARCHAR2(255)
);

CREATE TABLE Orders (
    id NUMBER PRIMARY KEY,
    client_id NUMBER REFERENCES Clients(id),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    total_amount NUMBER,
    status VARCHAR2(50)
);

CREATE TABLE OrderHistory (
    id NUMBER PRIMARY KEY,
    order_id NUMBER REFERENCES Orders(id),
    status VARCHAR2(50),
    changed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    note VARCHAR2(255)
);
```

### Объяснение структуры:

1. **Таблица клиентов** хранит базовую информацию о клиентах. Это позволит связывать заказы с конкретными клиентами.

2. **Таблица заказов** содержит информацию о каждом заказе, его сумме, статусе и дате создания.

3. **Таблица истории заказов** фиксирует изменения статуса заказов. Каждая запись в этой таблице будет содержать информацию о статусе на определенный момент времени, что позволит просматривать все обновления истории.

### Работа с историей заказов:

При изменении статуса заказа необходимо добавлять новую запись в таблицу `OrderHistory`. Например, при смене статуса заказа с "Ожидание" на "Выполнен" нужно вставить новую запись в историю:

```sql
INSERT INTO OrderHistory (order_id, status, changed_at, note)
VALUES (:order_id, 'Выполнен', CURRENT_TIMESTAMP, 'Заказ выполнен.');
```

Таким образом, текущий статус заказа можно получить из таблицы `Orders`, а полную историю статусов — из таблицы `OrderHistory`.

### Преимущества такой структуры:

- Упрощенная работа с данными: использование простых типов данных вместо JSON облегчает запросы и анализ данных.
- Возможность отслеживания всех изменений по каждому заказу.
- Легкость в расширении функционала: при необходимости добавления новых атрибутов в историю или заказ можно легко изменить структуру таблиц. 

Эта структура позволяет эффективно управлять историей заказов и поддерживать целостность данных в вашей базе данных.
Если я правильно вас понял, то в истории заказа вам не нужно хранить весь слепок заказа (ибо там ничего кроме статуса не меняется, в том числе - и в зависимой таблице Готовые_фото), а нужны только идентификатор заказа, статус заказа (то есть, его идентификатор в справочнике) и дата обновления. 

В таком случае всё просто: замените поле слепок_заказа полем, содержащим ссылку (внешний ключ) на запись справочника статусов заказа с нужным статусом.

Если нет - тогда придется объяснить нам тут схему того JSON слепка, который вы там храните, и что в этом слепке может поменяться.
Похожие вопросы