我有一个数据库设计和关系的问题,我关心可能的循环引用。
举个例子,杰克的库存中有药品A、B和C。药品A和B有active_ingredient AI1,药品C有active_ingredient AI2。
杰克去看医生,医生给他开了AI1。对于处方对象来说,服用A药还是B药无关紧要。
下面是一个示例代码:
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类连接了Person和me。
发布于 2019-05-29 03:43:56
您关注重复信息是正确的;数据库设计(特别是数据库规范化)的一个主要关注点是避免重复信息,从而消除不一致数据的可能性。
然而,在这种情况下,我认为将处方和配药分开更有意义。这是两件不同的事情,在现实世界中,很可能会犯错误,也很可能送错了药。虽然人们应该努力防止这样的错误,但这与不可能在数据模型中表示错误是截然不同的。
因此,我的建议是在应用程序层使用validate the data,而不是在数据模型本身中构建约束。类似于:
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
时进行检查。
https://stackoverflow.com/questions/56346957
复制相似问题