人谁开发数据库驱动的Web应用程序的小MySQL知道操作创建、检索、更新和删除表的关系型数据库是相对简单的过程。理论上,只要你掌握最常用的SQL语句的使用和熟悉的服务器端脚本语言,你选择,你会能够应付各种各样的MySQL表所需的操作,尤其是当你使用快速MyISAM数据库引擎,但即使在最简单的情况下,事情比我们想像的要复杂得多。让我们说明一个典型的例子。假设你正在运行一个博客网站,你几乎每天都更新,和网站允许游客评论你的文章。



在这种情况下,我们的数据库架构应该包括至少两个MyISAM表,一个用于存储您的博客文章,另一个用于处理游客的意见。很明显,有一到两个表之间的诸多关系,因此我们需要定义第二表的外键,这样我们可以保持数据库的完整性在更新或删除数据行。



应用以上既维持两个表的完整性是一个严峻的挑战,但最大的困难是,我们要保持其完整性,在应用层面,这是大多数Web项目不需要使用事务过程中采取的发展方式,因为MyISAM表提供了优良的性能。



当然,这样做是有代价的。正如我之前提到的,应用程序必须保持数据的完整性和一致性,这意味着我们需要实现更复杂的编程逻辑处理的表之间的关系。虽然抽象层和ORM模块可以用来简化数据库访问逻辑需要处理,他们也会变得更复杂的应用程序所需的数据表数量的增加。



因此,对于MySQL,没有办法处理外键数据库级别,以帮助维护数据库的完整性。幸运的是,答案是肯定的!MySQL InnoDB也支持,这样我们就可以在一个非常简单的方法来处理外键约束。此功能使我们能够触发某些动作,如更新和删除表中的数据线,以保持一个预定义的关系。



利各有弊。使用InnoDB表的主要缺点是,他们是比MyISAM慢,尤其是在大型的应用程序,需要查询多表。另外,新版本的MySQL的MyISAM表还支持外键约束。



本文将展示如何使用外键约束的InnoDB表。此外,我们将使用一个基于MySQL的抽象类简单的PHP创建示例代码。当然,您也可以使用其他您喜欢的服务器端语言。现在,我们开始介绍如何将外键约束应用到MySQL中。



使用外键约束的时间

说实话,在MySQL中使用InnoDB表的时候,它并不总是需要使用外键约束。然而,对于外键约束的作用,在某些情况下,我们将通过上述代码做出具体的解释。它包括两MyISAM表,它是用来存储博客文章和评论,分别。

当我们定义数据库模式时,我们需要在两个表之间建立不止一个关系。的方法是创建一个外键表中存储的评论,以便对应数据行(即注释)数据库中。以下是创建示例MyISAM表的基本SQL代码:

U3000 U3000


如果存在测试,则删除表;

创建表(测试

` ID ` int(10)无符号auto_increment,

` `标题文本,

'内容'文本,

`作者` varchar(45)默认为空,

prirose关键(` ID `)

= MyISAM引擎默认的字符集utf8);


如果存在测试注释,则删除表;

创建表(测试注释)

` ID ` int(10)无符号auto_increment,

` blog_id ` int(10)符号默认为空,

评论文本,

`作者` varchar(45)默认为空,

prirose关键(` ID `)

= MyISAM引擎默认的字符集utf8);






以上,我们只是定义了两MyISAM表形式的博客应用程序的数据层。正如你所看到的,第一个表称为博客,它是由一些重要的领域,它是用来存储ID,每一个博客文章的标题和内容,最后是作者的第二台。所谓的评论,这是用来存储每个博客文章的相关评论。它将博客文章的ID作为外键,并建立了一对多关系。



到目前为止,我们的工作是很容易的,因为我们刚刚创建的两个简单的MyISAM表。下一步,我们需要填写这些表格的一些记录,这样我们就可以进一步证明,当我们删除表项在第一个表,我们应该在另一个表中执行这些操作。

更新和维护数据库的完整性



在前面的章节中,我们创建了两个MyISAM表作为博客应用程序的数据层。当然,介绍的很简单,我们需要做进一步的探讨。为此,我们将在这些表中大量使用SQL命令的记录,如下图所示:

U3000 U3000


插入博客(ID,标题,内容,作者)值(null,标题的)

插入评论(ID,blog_id,评论作者)值(null,1,'commenting,第一,null,ID),(1)




上面的代码实际上模拟了读者苏珊和罗斯在我们的第一个博客上发表的评论。假设我们现在要用另一篇文章来更新第一个博客。当然,这是可能的。



在这种情况下,为了保持数据库的一致性,必须通过手动或通过处理数据层应用程序来更新注释表:


更新博客集ID = 2,标题=第一个博客条目的标题。

更新评论集blog_id = 2,blod_id = 1




如前所述,由于第一个blog的数据项的内容已被更新,注释表也必须反映这一变化。当然,实际上,更新操作应该在应用程序级完成,而不是手动完成,这意味着必须使用服务器端语言实现该逻辑。



为了完成此操作,可以通过PHP的简单子过程来完成,但实际上,如果使用外键约束,则可以将注释表的更新操作完全委托给数据库。



正如前面文章中提到的,InnoDB MySQL表提供了这一功能的无缝支持。所以,在后者的一部分,我们将使用外键约束重新前面的示例代码。

数据库的级联更新

下面,我们将重建前面的示例代码使用外键约束和InnoDB表(而不是默认的MyISAM类型)。要做到这一点,首先,你应该重新定义这两样表让他们可以使用一个特定的数据库引擎。为此,您可以使用SQL代码如下所示下面:

U3000 U3000


如果存在测试,则删除表;

创建表(测试

` ID ` int(10)无符号auto_increment,

标题文本,

'内容'文本,

`作者` varchar(45)默认为空,

prirose关键(` ID `)

InnoDB引擎=默认的字符集utf8);


如果存在测试注释,则删除表;

创建表(测试注释)

` ID ` int(10)无符号auto_increment,

` blog_id ` int(10)符号默认为空,

评论文本,

`作者` varchar(45)默认为空,

prirose关键(` ID `),

关键` blog_ind `(` blog_id `),

约束` comments_ibfk_1 `外键(` blog_id `)参考`博客`(` ID `)级联更新

InnoDB引擎=默认的字符集utf8);




代码和以前的代码之间最明显的区别是,两表现在使用InnoDB存储引擎,所以他们可以支持外键约束。除此之外,我们还需要注意代码定义的意见表:



U3000 U3000


约束` comments_ibfk_1 `外键(` blog_id `)参考`博客`(` ID `)级联更新





事实上,这种说法是通知mysqlmysql,当博客表被更新,在评论中表的外键blog_id价值也更新。备注

据说我们在这里所做的工作是让MySQL通过级联来维护数据库的完整性。这意味着,当博客更新时,与之相关联的注释也会立即作出反应。重要的是,在应用程序级别上不能完成此功能的实现。



已经定义了两个示例MySQL表。现在,更新这两个表就像运行一个UPDATE语句一样简单,如下所示:




更新博客集ID = 2,标题=






正如前面提到的,我们不需要更新的意见表,因为MySQL会自动处理这一切。此外,当试图更新博客表的数据行,您也可以删除查询或不行动更新MySQL和限制,让MySQL做什么。当然,你也可以让MySQL做其他的事情,这将在后续的文章。



通过上述,我认为我们必须与外键约束在MySQL InnoDB表有一个清晰的认识,当然,你也可以写更多的代码,进一步深化这一方便的数据库功能的理解。