Каков предпочтительный способ хранения деталей модели в django? - PullRequest
0 голосов
/ 28 апреля 2020

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

Моя текущая модель для Ингредиента и связанного NutrientProfile выглядит следующим образом:

class Ingredient(models.Model):
    ingredient_id = models.UUIDField(
        verbose_name="Ingredient",
        primary_key=True,
        default=uuid.uuid4,
        editable=False,
    )
    name = models.CharField(max_length=300, unique=False)
    synonyms = models.CharField(max_length=300, blank=True, null=True)
    category = models.CharField(max_length=300, blank=True, null=True)

class NutrientProfile(models.Model):
    nutrientProfileID = models.UUIDField(
        primary_key=True, default=uuid.uuid4, editable=False,
    )
    # Ingredient the NutrientProfile is associated to
    ingredient = models.ForeignKey(
        to="Ingredient",
        related_name='nutrientProfile',
        on_delete=models.CASCADE,
        blank=True,
        null=True,
    )
    fat_total = models.DecimalField(max_digits=7, decimal_places=4, blank=True, null=True)
    protein = models.DecimalField(max_digits=7, decimal_places=4, blank=True, null=True)
    cholesterol = models.DecimalField(max_digits=7, decimal_places=4, blank=True, null=True)
    ... more nutrients

Так что в настоящее время я могу создать Ингредиенты и связать их с одним или несколькими NutrientProfiles . Я не определял это отношение как «один-к-одному», потому что для одного ингредиента (нескольких источников данных) может быть несколько NutrientProfiles.

Теперь проблема: я понял, что мне потребуется дополнительная информация о каждое питательное вещество, такое как единица измерения, комментарий, дата добавления, ... Итак, я придумал следующие модели для включения таких деталей:

class NutrientProfile(models.Model):
    NutrientProfileID = ... ID
    ingredient = ... FK
    fat_total = models.OneToOneField("Nutrient", on_delete=models.CASCADE)
    protein = models.OneToOneField("Nutrient", on_delete=models.CASCADE)
    cholesterol = models.OneToOneField("Nutrient", on_delete=models.CASCADE)
    ... more nutrients

class Nutrient(models.Model): 
    amount = models.DecimalField(max_digits=7, decimal_places=4, blank=True, null=True)
    unit = models.CharField(max_length=5, choices=allowed_units)
    comment = models.CharField(max_length=200)
    ...

Итак, каждое поле в NutrientProfile может содержать все необходимые данные в модели Nutrient . Имеет ли это смысл, или я иду в неправильном направлении? Было бы лучше хранить все детали в самом NutrientProfile ? Как и так?

class NutrientProfile(models.Model):
    NutrientProfileID = ... ID
    ingredient = ... FK
    fat_total = models.OneToOneField("Nutrient", on_delete=models.CASCADE)
    fat_total_amount = ...
    fat_total_comment = ...
    fat_total_unit = ...
    protein = models.OneToOneField("Nutrient", on_delete=models.CASCADE)
    protein_amount = ...
    ... more nutrients

Определение всех деталей вместе, мне кажется очень уродливым. Но размещение их в другой таблице значительно увеличит «работу» базы данных, верно? Для 10000 NutrientProfiles с каждыми 30 питательными веществами в таблице Nutrient уже будет 300000 строк. Разве это не было бы гораздо более неэффективно, чем просто хранить больше столбцов в таблице NutrientProfile ? Я использую PostgreSQL в качестве базы данных прямо сейчас.

А, на мой взгляд, более гибким способом работы с деталями было бы определение моделей NutrientProfile и Nutrient , например:

class NutrientProfile(models.Model):
    NutrientProfileID = ... ID
    ingredient = ... FK
    # No defined nutrient fields

class Nutrient(models.Model): 
    nutrient_profile = models.ForeignKey('NutrientProfile', on_delete=models.CASCADE, null=False)
    # Nutrient type. For example: fat, protein, cholesterol,...
    # Maybe limited with predefined choices?
    nutrient_type = models.CharField(max_length=50, choices=??)
    amount = models.DecimalField(max_digits=7, decimal_places=4, blank=True, null=True)
    unit = models.CharField(max_length=5, choices=allowed_units)
    comment = models.CharField(max_length=200)
    ... more details
    class Meta:
        unique_together = ['nutrient_profile', 'nutrient_type']

Однако мой вопрос остается прежним. Является ли предпочтительным хранить больше полей в одной модели, или я должен разделить свои модели, даже если полученная таблица подробностей будет иметь больше строк? Как это влияет на производительность SQL?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...