问题是概念性的(数据库关系),因此语言不是这里的重点,但我正在使用 Python 和 Django。我有 3 个模型/桌子:公司顾客地址例如。class Company(models.Model): name = models.CharField(max_lenght=100) #exampleclass Customer(models.Model): name = models.CharField(max_lenght=100) #exampleclass Adress(models.Model): country = models.CharField(max_lenght=100) #example state = models.CharField(max_lenght=100) #example # here I want the address owner # I could put something like this: company = models.ForeignKey(Company, on_delete=models.PROTECT) customer = models.ForeignKey(Customer, on_delete=models.PROTECT)我希望该地址属于客户或公司,但不能同时属于两者。我知道我可以简单地创建 2 个地址类,例如 CustomerAddress、CompanyAddress,每个类都有其正确的外键:class Company(models.Model): name = models.CharField(max_lenght=100) #exampleclass Customer(models.Model): name = models.CharField(max_lenght=100) #exampleclass CompanyAdress(models.Model): country = models.CharField(max_lenght=100) #example state = models.CharField(max_lenght=100) #example company = models.ForeignKey(Company, on_delete=models.PROTECT)class CustomerAdress(models.Model): country = models.CharField(max_lenght=100) #example state = models.CharField(max_lenght=100) #example customer = models.ForeignKey(Company, on_delete=models.PROTECT)但我不想这么做,原因有两个:重复的代码以及在 Django 管理面板中我将有两个单独的地址列表的事实,这没有多大意义,因为所有地址在结构上都是相同的。我可以修复创建基类、继承基类等的重复代码,但我在管理面板中仍然会有 2 个列表。将来我可能会遇到同样的概念性问题,但会更加复杂,例如,某些事物有 300 个类,而 1 个类应该只有 300 个类中的一个具有外键。我应该怎么办?
2 回答
牧羊人nacy
TA贡献1862条经验 获得超7个赞
您可以尝试将外键设置为 null=True 并根据需要通过视图控制数据库中的输入:
class Address(models.Model): country = models.CharField(max_lenght=100) state = models.CharField(max_lenght=100) company = models.ForeignKey(Company, on_delete=models.PROTECT, null=True) customer = models.ForeignKey(Customer, on_delete=models.PROTECT, null=True)
千万里不及你
TA贡献1784条经验 获得超9个赞
下面是一个DB模型。
-- Address ADR exists. -- address {ADR} PK {ADR}
Party
是个人或组织的通用术语;判别器TYP
用于区分两者。
-- Party PTY, of party-type TYP, resides at address ADR. -- party {PTY, TYP, ADR} PK {PTY} SK {PTY, TYP} CHECK TYP in {'P', 'O'} FK {ADR} REFERENCES address {ADR}
-- Person, a party PTY of party-type TYP = 'P', exists. -- person {PTY, TYP} PK {PTY} CHECK TYP = 'P' FK {PTY, TYP} REFERENCES party {PTY, TYP}
-- Organization, a party PTY of party-type TYP = 'O', exists. -- organization {PTY, TYP} PK {PTY} CHECK TYP = 'O' FK {PTY, TYP} REFERENCES party {PTY, TYP}
笔记:
All attributes (columns) NOT NULL PK = Primary Key AK = Alternate Key (Unique) SK = Proper Superkey (Unique) FK = Foreign Key
关于亚型的一句话。实现子类型约束的正确方法是使用断言(CREATE ASSERTION
),但它在主要数据库中仍然不可用。我正在使用FKs
它,并且与所有其他替代方法一样,它并不完美。人们争论很多,关于SO和SE-DBA,哪个更好。我鼓励您也检查其他方法。
添加回答
举报
0/150
提交
取消