2011-06-05 90 views
1

我有以下兩個MySQL表的基本論壇。第一個表格包含主題,第二個表格包含對特定主題的回覆。 我想知道這個數據庫設計中的外鍵概念。我需要在這裏添加外鍵嗎?它將如何有用,以及如何添加下列表格。謝謝。我的數據庫表中是否需要外鍵?

-- 
-- Table structure for table `topics` 
-- 

CREATE TABLE IF NOT EXISTS `topics` (
    `topic_id` int(11) NOT NULL AUTO_INCREMENT, 
    `topic_title` varchar(255) NOT NULL, 
    `topic_content` text NOT NULL, 
    `topic_author_id` int(11) NOT NULL, 
    `topic_date` int(10) NOT NULL, 
    PRIMARY KEY (`topic_id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; 

-- 
-- Table structure for table `replies` 
-- 

CREATE TABLE IF NOT EXISTS `replies` (
    `reply_id` int(11) NOT NULL AUTO_INCREMENT, 
    `reply_topic_id` int(11) NOT NULL, 
    `reply_content` text NOT NULL, 
    `reply_author_id` int(11) NOT NULL, 
    `reply_date` int(10) NOT NULL, 
    PRIMARY KEY (`reply_id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; 

回答

2

一般來說MySQL不要求你插入外鍵。而且,只要你使用MyISAM存儲引擎,你就不能從定義外鍵獲益。他們接受外鍵語法,但內部他們只是忽略這些語句,詳情請參閱foreign key entry in MySQL documentation

相反,您可能會考慮爲外鍵列定義其他索引,這可能會提高查詢性能。您可以定義一個索引以及您的表格定義

CREATE TABLE IF NOT EXISTS `replies` (
    `reply_id` int(11) NOT NULL AUTO_INCREMENT, 
    `reply_topic_id` int(11) NOT NULL, 
    `reply_content` text NOT NULL, 
    `reply_author_id` int(11) NOT NULL, 
    `reply_date` int(10) NOT NULL, 
    PRIMARY KEY (`reply_id`), 
    INDEX (`reply_topic_id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; 

有關詳細信息,請參閱mysql create table syntax

作爲替代方案,您可能會考慮將存儲引擎更改爲InnoDB,並使用外鍵將索引自動添加到所需的列中。但是,如果您真的需要性能優化之外的其他功能,例如foreign key constraints,那麼您只會受益。作爲一個經驗法則,我們可以堅持mysql手冊中給出的建議。如果您不需要額外的好處,如MyISAM存儲引擎將提供更好的性能。因此,如果您不希望數據庫確保參照完整性,而是在您的應用程序中自行完成此操作,那麼具有適當索引的MyISAM將是更快,更好的執行解決方案。如果您希望數據庫確保參照完整性,那麼切換到InnoDB存儲引擎並使用適當的約束來定義外鍵。

+0

感謝您的回覆。你可以給我一個例子,我可以如何添加索引到上面的兩個表? – Roman 2011-06-05 12:03:19

+0

再次感謝您的回覆。您能告訴我哪種方法更好,通過將存儲引擎更改爲InnoDB來添加索引或使用外鍵。我只關心性能等。 – Roman 2011-06-05 13:21:40

+0

@Roman:包括一些關於何時切換到InnoDB的建議。希望對你的決定有所幫助。 – Steffen 2011-06-05 14:11:53

1

replies表應該包含主題的topic_id中這在replies表中特定的回覆是爲topics表中的列。

例如

`topic_id` int(11) FOREIGN KEY REFERENCES `topics`(`topic_id`) 
+0

但我已經在回覆表'reply_topic_id'中有一列,這個名字是好的,還是應該是確切的'topic_id'?在表中添加外鍵有什麼好處? – Roman 2011-06-05 12:01:20

+0

我錯過了'reply'表中的'reply_topic_id'。我應該更仔細地閱讀這個問題。不,該列的名稱不必與它所指的列的名稱相同。因此,您只需要添加: 'reply_topic_id' int(11)FOREIGN KEY REFERENCES'topics'('topic_id') 添加外鍵可啓用參照完整性檢查。無論何時,在「答覆」表中插入新行時,RDBMS都會確保新行的「reply_topic_id」列包含「topics」表的「topic_id」列中存在的值。如果沒有,它會通知你一個錯誤。 – 2011-06-05 12:10:32

3

外鍵在技術上沒有要求 - 但從數據質量的角度來看,強烈建議。

外鍵建立兩個表之間的關係 - 它定義並保證:

  • 你不必引用父行(topics)任子行(在replies)那並不「T存在(‘殭屍數據’)

  • 它確保你不小心刪除父行,只要還有周圍

子行

一般來說,它確保您的數據的質量和完整性 - 數據庫中強烈推薦的屬性!

相關問題