我的数据库表中是否需要外键?

时间:2011-06-05 11:50:43

标签: foreign-keys

我有两个基本讨论论坛的mys​​ql表。第一个表包含主题,第二个表包含对特定主题的回复。 我想知道这个数据库设计中的外键概念。我需要在这里添加外键吗?它将如何有用,如何在下表中添加。感谢。

--
-- 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 ;

3 个答案:

答案 0 :(得分:3)

外键在技术上并不需要 - 但从数据质量的角度来看,强烈建议使用外键。

外键在两个表之间建立关系 - 它定义并确保:

  • 您没有任何子行(在replies中)引用不存在的父行(在topics中)(“zombie data”)

  • 只要还有子行,

  • 确保您不会意外删除父行

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

答案 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存储引擎并使用适当的约束定义外键。

答案 2 :(得分:1)

replies表应该有一个列,其中包含topic_id表中主题的topicsreplies表中的特定回复适用于该表。 / p>

e.g。

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