2010-02-04 100 views
0

我有一個表管理網站的虛擬下載文件夾。外鍵約束(複雜?)

CREATE TABLE `folder` (
    # id = PK 
    `id` int(10) unsigned NOT NULL auto_increment, 
    # folderId = self referencing FK to id 
    `folderId` int(10) unsigned default NULL, 
    # siteId = FK to id in site table 
    `siteId` int(10) unsigned NOT NULL 
) 

理想我喜歡siteId在表folder引用id在表site,但也有一個化合物FK folderId, siteId是自參考到id, siteId

我想這樣做的原因是我想保證子文件夾始終與父文件夾屬於同一站點。

是這樣的可能嗎?如果是這樣,怎麼樣?如果不是,你有任何其他建議如何保證這個狀態?

編輯:
對不起,我應該提到這早些時候:我知道的InnoDB,並作爲事實上,我已經在使用它(與外鍵)。但問題是,我如何能夠保證這兩個東西:

  • folder紀錄必須引用有效sitesiteId
  • folder A記錄也必須相同siteId,作爲父記錄(僅當它是當然的孩子)

我想這個至今:

# this one should guarantee folder belongs to 
    # a valid site (this one works of course) 
    CONSTRAINT `FK_folder_site_1` 
    FOREIGN KEY (`siteId`) 
    REFERENCES `site` (`id`) ON UPDATE CASCADE, 

    # this one should guarantee child folder belongs to 
    # the same site as parent folder (doesn't work) 
    CONSTRAINT `FK_folder_folder_1` 
    FOREIGN KEY `FK_folder_folder_1` (`folderId`, `siteId`) 
    REFERENCES `folder` (`id`, `siteId`) ON DELETE CASCADE ON UPDATE CASCADE 

所以最後一個不起作用(當然?),因爲外鍵(siteId)不能引用兩個不同的字段似乎合乎邏輯。您可以建議如何使我提出的約束條件起作用?

+0

我不明白你爲什麼需要這兩個外鍵。第二個單獨應足以確保記錄引用有效的文件夾/站點組合。 – friedo 2010-02-05 05:47:11

回答

0

InnoDB存儲引擎支持自引用外鍵,您可以使用它們來模擬分層結構。要聲明的關鍵,你可以做這樣的事情在你的CREATE TABLE聲明:

FOREIGN KEY (`folderId`,`siteId`) REFERENCES `folder` (`Id`, `siteId`) 

需要記住的重要事情是,這個關鍵的應該是NULL -able,這樣你就可以指示哪個結果是根的樹。

+0

@friedo:謝謝,但我已經用外鍵使用InnoDB了。我已經更新了我的問題,以更清楚地說明問題(我希望)。你介意再看一下嗎?謝謝。 – 2010-02-04 20:56:01

0

如果你使用InnoDB存儲引擎

CREATE TABLE `folder` (
    # id = PK 
    `id` int(10) unsigned NOT NULL auto_increment, 
    # folderId = self referencing FK to id 
    `folderId` int(10) unsigned default NULL, 
    # siteId = FK to id in site table 
    `siteId` int(10) unsigned NOT NULL, 
    FOREIGN KEY (folder_id, site_id) REFERENCES folder(id, site_id) 
) ENGINE=INNODB; 

它沒有測試它,但它應該工作,你可以做到這一點。見FOREIGN KEY Constraints

如果您想要/必須使用MyISAM,當然您可以按照與「正常」外鍵約束相同的方式執行此操作。

+0

@Felix:謝謝,但我已經使用InnoDB和外鍵。我已經更新了我的問題,以更清楚地說明問題(我希望)。你介意再看一下嗎?謝謝。 – 2010-02-04 20:56:31