3

所以我繼承了一些django。瞭解/ mySQL又名欺騙Django中的ForeignKey關係

MySQL表很簡單,其中父母是不是一個FK的關係只是「父」 ID:

CREATE TABLE `Child` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `parent` int(10) unsigned NOT NULL, 
    `name` varchar(255) NOT NULL, 
    UNIQUE KEY `id` (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=24; 

但隨後的鼻祖這樣做..

class Child(models.Model): 
    """Project Child information""" 
    id = models.AutoField(primary_key=True) 
    parent = models.ForeignKey(Parent) 
    name = models.CharField(max_length=255) 

    class Meta: 
     managed = False 

誠然,我不是一個SQL騎師,但我知道一個「真正的」外鍵關係看起來類似於這個通知CONSTRAINT ...

CREATE TABLE `Child` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `parent_id` int(11) NOT NULL, 
    `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL, 
    PRIMARY KEY (`id`), 
    KEY `child_63f17a16` (`parent_id`), 
    CONSTRAINT `parent_id_refs_id_34923e1e` FOREIGN KEY (`parent_id`) REFERENCES `Parent` (`id`) 
) ENGINE=InnoDB; 

我想知道的是以下內容:

  1. 我可以期待通過這個「欺騙」看到什麼問題。
  2. 雖然這似乎工作 - 是否建議或建議。
  3. 我們會建議將SQL修改爲add in the constraint嗎?

非常感謝!

回答

1
  1. 沒有一個實際的約束可能會導致引用失敗,父母無效和其他類型的數據不一致。我不是一個Django專家,但我會冒險猜測,在大多數情況下,除非有意添加一些無效記錄,否則Django仍然會處理關係。

  2. 通常情況下,如果你的RDBMS支持外鍵約束,那絕對沒有理由不使用它們,它可能被認爲是一個忽略它們的設計缺陷。

  3. 您應該考慮添加關鍵約束。他們不僅爲您的DBMS提供了一個關於如何優化查詢的好主意,還確保了數據的一致性。我敢肯定的Django有一個設置的地方,會自動生成SQL當您運行manage.py syncdb

添加的主要制約因素有關,爲什麼你應該更喜歡外鍵的更多信息,請閱讀MySQL Foreign Key Documentation

最有意思的是:

InnoDB需要外鍵和引用鍵的索引,以便外鍵檢查可以快速且不需要表掃描。在引用表中,必須有一個索引,其中外鍵列以相同順序排列爲第一列。如果索引表不存在,則會在引用表上自動創建這樣的索引。 (這與一些較早的版本形成對比,在這些版本中索引必須明確創建,否則外鍵約束的創建將失敗。)如前所述,使用index_name(如果已給定)。

+0

這真的是一個很好的信息 - 非常感謝您的詳細回覆 - 我當然同意你沒有它的問題。這就是說,你看到的問題只是將它分配爲FK而沒有強加這些限制?這當然會使我的查詢更簡單... – rh0dium

+0

我不知道你的意思是不強制約束。在InnoDB中,當你有'FOREIGN KEY REFERENCES'時,它會自動創建和執行存在約束。您不需要'CONSTRAINT'子句。 – alxbl

+0

措辭不當。你是否看到過在Django中將其定義爲ForeignKey的問題,而不是在db級別上強加它; notice managed = False – rh0dium

0

它應該會更快......因爲你的mysql在子表中添加一行之前沒有檢查約束。 但是用外鍵,它會讓你的生活更輕鬆,因爲你可以使用on update和delete。 我會去約束。

+1

除非您手動將索引添加到外鍵字段,否則速度不會更快。如果你打算這樣做,那麼你也可以用外鍵一路通過。無論哪種方式,您將擁有一個頁面I/O,並且檢查約束也是一個頁面I/O。這意味着插入時可能會有一個小的(通常是無關緊要的)缺點,但是您可以100%確定表中沒有引用錯誤。 – alxbl