亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

我如何限制或選擇一個或另一個外鍵?

我如何限制或選擇一個或另一個外鍵?

qq_花開花謝_0 2023-07-05 15:30:09
問題是概念性的(數據庫關系),因此語言不是這里的重點,但我正在使用 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)


查看完整回答
反對 回復 2023-07-05
?
千萬里不及你

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,哪個更好。我鼓勵您也檢查其他方法。


查看完整回答
反對 回復 2023-07-05
  • 2 回答
  • 0 關注
  • 169 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號