2011-06-05 86 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存在(‘僵尸数据’)

  • 它确保你不小心删除父行,只要还有周围

子行

一般来说,它确保您的数据的质量和完整性 - 数据库中强烈推荐的属性!

相关问题