модели django - избегайте возможных циклических ссылок в дизайне базы данных - PullRequest
0 голосов
/ 28 мая 2019

У меня проблема с дизайном базы данных и отношениями, и меня интересуют возможные циклические ссылки.

Чтобы привести пример, у Джека есть в запасе Лекарства A, B и C. Лекарства A и B имеют AI_ active_redredient, а лекарство C имеет AI2 active_ingredient.

Джек идет к врачу, который прописывает ему AI1. Для объекта «Рецепт» безразлично, принимает ли он лекарство А или Б.

Вот пример кода:

class ActiveIngredient(models.Model):
    ...

class Medicine(models.Model):
    quantity = models.IntegerField()
    active_ingredient = models.ForeignKey("ActiveIngredient", on_delete=models.CASCADE)

class Person(models.Model):
    ...

class PersonStock(models.Model):
    customer = models.ForeignKey("Person", on_delete=models.CASCADE)
    medicine = models.ForeignKey("Medicine", on_delete=models.CASCADE)
    expiration_date = models.DateField()

class Prescription(models.Model):
    ...
    quantity = models.IntegerField()

Какое лучшее решение для моделирования этих отношений?

Изменение рецепта на это:

class Prescription(models.Model):
    ...
    customer = models.ForeignKey("Person", on_delete=models.CASCADE)
    active_ingredient = models.ForeignKey("ActiveIngredient", on_delete=models.CASCADE)
    quantity = models.IntegerField()

Мне кажется неправильным, если учесть, что класс PersonStock уже связывает человека и лекарство.

1 Ответ

1 голос
/ 28 мая 2019

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

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

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

class ActiveIngredient(models.Model):
    ...

class Medicine(models.Model):
    quantity = models.IntegerField()
    active_ingredient = models.ForeignKey("ActiveIngredient", on_delete=models.CASCADE)

class Person(models.Model):
    ...

class Prescription(models.Model):
    ...
    customer = models.ForeignKey("Person", on_delete=models.CASCADE)
    active_ingredient = models.ForeignKey("ActiveIngredient", on_delete=models.CASCADE)
    quantity = models.IntegerField()

class PersonStock(models.Model):
    prescription = models.ForeignKey("Prescription", on_delete=models.CASCADE)
    medicine = models.ForeignKey("Medicine", on_delete=models.CASCADE)
    expiration_date = models.DateField()

    # Make sure the supplied medicine is correct.
    def clean(self):
        if self.medicine.active_ingredient != self.prescription.active_ingredient:
            raise ValidationError("Wrong medicine!")

В качестве альтернативы вы можете выполнить проверку только при создании PersonStock.

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