Целесообразно ли упрощать разработку вариантов продукта, используя примечания вместо сложных отношений?

Я создаю приложение, в котором варианты продуктов должны обрабатываться как физические продукты, уже подготовленные и перечисленные вручную. Вместо того чтобы использовать традиционный подход со сложными отношениями между таблицами Product, Option, OptionValue и SKUValue, я пытаюсь упростить конструкцию.

💡 ERD Design:

+--------------+        +-----------------+
|   Product    |        |  ProductVariant  |
+--------------+        +-----------------+
| id (PK)      |<------>| id (PK)          |
| name         |        | product_id (FK)  |
| owner_id (FK)|        | note             | 
| created_at   |        | stock            |
| updated_at   |        | price            |
+--------------+        +-----------------+

В таблице ProductVariant поле примечания представляет собой простое текстовое поле, в которое пользователи могут вручную вводить описания типа "Size: XL, цвет: красный".

🔍 Модели Django, основанные на этом дизайне:

from django.db import models
from django.contrib.auth import get_user_model

User = get_user_model()

class Product(models.Model):
    name = models.CharField(max_length=255)
    owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='products')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.name


class ProductVariant(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='variants')
    note = models.TextField()  # Example: "Size: XL, Color: Red"
    stock = models.PositiveIntegerField()
    price = models.DecimalField(max_digits=10, decimal_places=2)

    def __str__(self):
        return f"{self.product.name} - {self.note}"

🎯 Почему я это делаю:

  1. Приложение предназначено для работы с вариантами продукции, которые часто предопределены и не меняются динамически.
  2. Пользователи будут вручную вводить описания вариантов на основе реальных физических продуктов, которые у них есть.
  3. Цель - избежать чрезмерной инженерии, устранив лишние таблицы и связи.

🤔 О чем я беспокоюсь:

  • Я знаю, что большинство приложений используют хорошо структурированные реляционные модели для управления вариантами продукции.
  • Однако реализация таких сложных структур кажется излишней для моего случая использования, и я беспокоюсь, что это может создать ненужные сложности.
  • Меня беспокоит, что такой упрощенный подход может считаться "плохим дизайном", даже если он лучше подходит для моего случая использования.

❓ Вопрос:

Приемлема ли эта упрощенная конструкция, использующая ручные заметки для вариантов продукции, в сценариях, где варианты предопределены и записываются вручную? Какие потенциальные «подводные камни» я должен знать при использовании этой конструкции по сравнению с более «стандартной» реляционной моделью?

Что бы я подумал в этой ситуации, так это то, что теперь у вас есть столбец, состоящий из значений, основанных на словаре... И я бы не рекомендовал этого делать по нескольким причинам:

  1. проверка будет сложнее, и у вас может быть возможность выполнять только мягкую проверку с использованием обработки django (а не жесткую проверку базы данных, которая является более согласованной).

  2. размер этой таблицы будет больше по сравнению с таблицей с разделенными столбцами указанной роли.

  3. использование фильтров по текстовому полю происходит медленнее (например, если вы хотите отобразить все продукты, которые выделены красным цветом).

В некоторых случаях такие столбцы могут подойти больше, если вы не гарантируете, что у вас всегда будут значения в столбцах параметров (разреженные таблицы). В случае разреженной таблицы у вас может быть столбец note, и вы можете удалить пустые параметры.

Другое дело, что вы должны помнить о том, что ваш дизайн можно расширять, и вы всегда можете добавить к нему дополнительные функции, и, конечно, вы должны учитывать меняющиеся требования, например, что, если вдруг вам придется изменить некоторые параметры продукта, тогда у вас будет чтобы выполнить итерацию по столбцу note и изменить значения каким-либо несогласованным образом.

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

Текущий дизайн

Для поля note: попробуйте использовать JSONField ( (хотя обратите внимание на пункт о совместимости с базой данных) вместо TextField.

Сохранение заметок в виде структурированных данных упростит синтаксический анализ во внешнем интерфейсе и значительно упростит поиск/фильтрацию/и т.д. во внутреннем интерфейсе (в частности, если вы используете Postgres, смотрите примечания к PG в связанной документации). Это также позволяет вам хранить более одного значения, а также метаданные и инструкции по синтаксическому анализу (например, размер шрифта, цвет или что-то еще, что вам нравится) атрибута.

Пример:

[
    {
        "1": {
            "title": "Size",
            "us_value": "XL",
            "eu_value": 50,
            "title_color": "red",
            "value_color": "blue"
        }
    }
]

Возможные подводные камни:

  • Этот подход быстро развалится, если вы захотите позволить пользователю добавлять сложные данные (т.е. любые данные, которые "превосходят" то, что легко вписывается в парадигму ключ-значение).
  • Агрегирование данных по пользовательским атрибутам будет сложным в реализации, даже если вы используете JSONField. Если вы используете TextField, это будет очень сложно по практическим соображениям.
  • Если не использовать структурированные данные, подобные описанному выше подходу в формате JSON, поиск и фильтрация будут практически невозможны, если только производительность не будет абсолютно нулевой.
  • Массовые обновления или любая ситуация, когда вам нужно обновить более одного экземпляра за раз, будут затруднительны как с точки зрения логики, так и с точки зрения производительности.

Альтернативный дизайн

"Сверхинженерный" подход, вероятно, был бы чем-то вроде набора EAV-моделей. Я знаю, что вы не просили конкретно об этом, но всегда полезно знать смежные концепции.

django-eav2 предоставляет хороший обзор EAV и вариантов его использования, и вы можете либо использовать библиотеку в этом ключе, если это кажется правильным, либо создать свою собственную, используя общие отношения.

Вернуться на верх