@MoDPhoenix

Планирование структуры базы данных для базы знаний по игре, что будет эффективнее?

Предисловие, есть готовый сайт на django с базой знаний по игре. Под капотом категории в базе знаний реализованы в отдельных таблицах postgresql c полями описание объекта и набором свойств для сравнения которые для каждой категории свои.

Пока категорий в базе не очень большое количество, и соответственно можно ее безболезненно переделать.

Хочу унифицировать объекты в базе в одну таблицу с полем описания объекта и и.д., а свойства и их значения вынести в две отдельные таблицы. После чего просто делать связь объекта со свойствами и их значениями.

Вопрос в том стоит ли это делать? И есть ли какие то другие варианты решения задачи?

upd.

Вот какую схему базы данных я имел виду, взял ее с онлайн магазина.

Модель категории, например: Оружие(подкатегория Мечи), Зелья, Доспепи и т.д.

class Category(MPTTModel, ModerationBaseModel):
    """
    Category of item
    extend ItemBaseModel
    which has slug, name,
    description, keywords
    """
    slug = models.CharField(
        _("Slug"),
        default="",
        unique=True,
        max_length=250)
    name = models.CharField(
        _("Name"),
        default="",
        max_length=250)
    title = models.CharField(
        _("Title"),
        blank=True,
        default="",
        max_length=250)
    description = models.CharField(
        _("Description"),
        blank=True,
        default="",
        max_length=250)
    keywords = models.CharField(
        _("Keywords"),
        blank=True,
        default="",
        max_length=250)
    parent = TreeForeignKey(
        'self',
        null=True,
        blank=True,
        related_name='children',
        verbose_name=_('Parent'))
    image = models.ImageField(
        upload_to='category_images/',
        blank=True,
        default="",
        verbose_name=_('Image'))

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = _('Category')
        verbose_name_plural = _('Categories')

    class MPTTMeta:
        order_insertion_by = ['name']


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

class Item(ModerationBaseModel):
    slug = models.CharField(
        _("Slug"),
        default="",
        blank=True,
        db_index=True,
        max_length=250)
    name = models.CharField(
        _("Name"),
        default="",
        max_length=250)
    title = models.CharField(
        _("Title"),
        blank=True,
        default="",
        max_length=250)
    description = models.CharField(
        _("Description"),
        blank=True,
        default="",
        max_length=250)
    keywords = models.CharField(
        _("Keywords"),
        blank=True,
        default="",
        max_length=250)
    image = models.ImageField(
        upload_to='Itemimeges/',
        blank=True,
        default="",
        verbose_name=_('Image'))
    category = models.ForeignKey(
        Category,
        on_delete=models.CASCADE,
        related_name='categories',
        blank=True,
        null=True,
        verbose_name=_('Category'))
    description = models.TextField(blank=True,)
    full_text = models.TextField(blank=True,)

    def save(self, *args, **kwargs):
        if self.category:
            super(Item, self).save(*args, **kwargs)
            # we create properties if not exist
            for cp in CategoryProperty.objects.filter(category=self.category):
                pp = ItemProperty.objects.filter(category_property=cp,
                                                 Item=self)
                if not pp:
                    pp = ItemProperty(category_property=cp,
                                      Item=self, value="--")
                    pp.save()

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = _('Item')
        verbose_name_plural = _('Items')


Модель для набора свойств в определенной категории, например: Категория Мечи - свойства урон, скорость, дпс и т.д.

class CategoryProperty(ModerationBaseModel):
    name = models.CharField(
        _("Name"),
        default="",
        max_length=250)
    category = models.ForeignKey(
        'Category',
        on_delete=models.CASCADE,
        related_name='categories_property',
        verbose_name=_('Category'))

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = _('Category property')
        verbose_name_plural = _('Category properties')


И последняя модель для хранения значений свойств конкретного объекта, например: "Ледяная Скорбь" - урон - 100, скорость - 20, дпс - 500.

class ItemProperty(ModerationBaseModel):
    category_property = models.ForeignKey(
        CategoryProperty,
        on_delete=models.CASCADE,
        related_name='category_property',
        verbose_name=_('Propery'))
    value = models.CharField(
        _("Value"),
        default="",
        max_length=250)
    Item = models.ForeignKey(
        'Item',
        on_delete=models.CASCADE,
        related_name='properties_Item',
        verbose_name=_('Item'))

    def __str__(self):
        return self.value

    class Meta:
        verbose_name = _('Item property')
        verbose_name_plural = _('Item properties')


Но получается что если в категории 100 страниц а у каждой страницы 10 свойств, выходит 100*10 = 1000 записей в базе данных, и еще плюс 10 других категорий 1000*10 = 10000 записей (при нынешней реализации это будет просто 1000 записей и 10 различных моделей для каждой категории).

Но при подходе с унифицированными страницами и отдельными свойствами (который я описал выше) все управление данными ведется с админки и добавляя новые категории не нужно править код моделей. Вот у меня и вопрос стоит ли все это того?

И еще я знаю реализации магазинов где категории товаров также жестко прописываются в моделях, вот пример Заготовка под магазин django-SHOP

За пример беру магазины, поскольку база знаний этот тот же самый магазин только без корзины =).
  • Вопрос задан
  • 793 просмотра
Пригласить эксперта
Ответы на вопрос 1
Stalker_RED
@Stalker_RED
И есть ли какие то другие варианты решения задачи?
Перенести всё на wikia.com

Примеры:
fallout.wikia.com/wiki/Fallout_Wiki
ru.left4dead.wikia.com/wiki/Left_4_Dead_2
ru.rimworld.wikia.com/wiki
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы