MySQL数据库(十四)__2018.11.18

外键约束的使用

在进行多表查询的时候,我们曾经插入过一个非法的数据(脏数据)是一个不合法的形式。当然我们在之前的测试中是可以写进去的。证明了我们这个表中有这样一个非法的数据,这个数据破坏的数据的一致性原则,完整性就得不到保证。那怎么样来得到保证呢,其实,我们可以通过外键约束来约束它。

外键约束(foreign key),这个外键的作用就可以保证我们这样一个数据表的一致性和完整性。

也可以通过外键实现这种一对一,一对多的关系。

在这里,我们来看一下,外键相关的内容。首先呢外键它是我们数据表的一个特殊字段。它可以参照我们的另一个表,我们叫做主表来创建一个我们这样一个从表。想创建外键需要注意几点:1.只有innodb的存储引擎支持外键。而且在创建外键的时候,我们的子表它必须是,字表的外键必须关联我们父表的主键。

#测试外键
#那么外键呢,它是一个表参照另外一个表的主键来创建的
#创建一个新闻分类表,模拟这么一个cms系统news_cate
#新闻分类表
CREATE TABLE news_cate(
	id TINYINT UNSIGNED AUTO_INCREMENT KEY,
	cateName VARCHAR(50)NOT NULL UNIQUE,
	cateDesc VARCHAR(100)NOT NULL DEFAULT ''
);

#新闻表news
CREATE TABLE news(
	id INT UNSIGNED AUTO_INCREMENT KEY,
	title VARCHAR(100)NOT NULL UNIQUE,
	content VARCHAR(1000)NOT NULL,
	cateId TINYINT UNSIGNED NOT NULL
);
#一定是先有分类,我们才能把新闻发布到指定的分类下
INSERT news_Cate(cateName)VALUES('国内新闻'),
('国际新闻'),
('娱乐新闻'),
('体育新闻');

INSERT news(title,content,cateId)VALUES('a1','aaaa1',1),
('a2','aaaa2',1),
('a3','aaaa3',4),
('a4','aaaa4',2),
('a5','aaaa5',3);

#查询new id title content
#news_cate cateName
SELECT n.id,n.title,c.cateName
FROM news AS n
#这里连接上另外一个表
JOIN news_cate AS c
#连接条件
ON n.`cateId`=c.`id`;

假设这么一种情况,新闻公司把国外新闻这一分类取消了,只报国内新闻。

我们就可以看到这么一种情况,国际新闻这么一个类别已经不存在了,但是在news这么一个表中,还存在着这么一条记录。这合适吗?

包括我们再来写一个非法的数据。

#插入一个非法的记录
INSERT news(title,content,cateId)VALUES('a6','aaaa6',45);
#首先我们看一下,有45这个分类吗?没有,都没有这么一个分类,
#怎么能让它插入成功呢,但是,SQL语句本身是没有错误的。

这就是我们所说的一个脏数据。

#包括更严重的,我们直接把新闻分类表删掉,
#我们可以看到这些新闻依然在这些分类下的
DROP TABLE news_cate;
SELECT *FROM news;

这合适吗?显然是不合适的,这时候就要用到我们的外键,它的作用就是保证数据的一致性和完整性。

创建外键的方式:1.在建表时指定外键:[constraint 外键名称]foreign key (字段名称)references 主表(字段名称)

首先呢,在创建外键的时候我们应该知道,我们的外键是依赖于主表的主键,所以说呢一定要先有主表。

那么什么叫主表呢?先有哪个,哪个就是主表,接下来创建外键的时候我们就会参照主表的主键来创建。

#测试外键
#那么外键呢,它是一个表参照另外一个表的主键来创建的
#创建一个新闻分类表,模拟这么一个cms系统news_cate
#新闻分类表
CREATE TABLE news_cate(
	id TINYINT UNSIGNED AUTO_INCREMENT KEY,
	cateName VARCHAR(50)NOT NULL UNIQUE,
	cateDesc VARCHAR(100)NOT NULL DEFAULT ''
)ENGINE=INNODB;

#新闻表news
CREATE TABLE news(
	id INT UNSIGNED AUTO_INCREMENT KEY,
	title VARCHAR(100)NOT NULL UNIQUE,
	content VARCHAR(1000)NOT NULL,
	cateId TINYINT UNSIGNED NOT NULL,
	#创建外键
	FOREIGN KEY(cateId)REFERENCES news_cate(id)
)ENGINE=INNODB;
#一定是先有分类,我们才能把新闻发布到指定的分类下

外键类型要和主键类型一致。长度可以不同,但是类型要相同。

表的外键字段和主表的主键字段类型要相似;如果是数值型,要求一致,并且无符号也要一致;如果是字符型,要求类型一致,长度可以不同。

创建外键后,会自动添加索引。

如果外键字段没有主键,外键会自动添加主键。

INSERT news_Cate(cateName)VALUES('国内新闻'),
('国际新闻'),
('娱乐新闻'),
('体育新闻');

INSERT news(title,content,cateId)VALUES('a1','aaaa1',1),
('a2','aaaa2',1),
('a3','aaaa3',4),
('a4','aaaa4',2),
('a5','aaaa5',3);

#测试删除父表中的记录 和删除父表
DELETE FROM news_cate WHERE id=1;

UPDATE news_cate SET id=10 WHERE id=1;

INSERT news_cate(cateName)VALUES('教育新闻');

#对字表没有影响的,修改是没有问题的。
UPDATE news_cate SET cateName='教育' WHERE id=5;
UPDATE news_cate SET id=50 WHERE cateName='教育';

对字表没有影响的,更新父表是可以的。

或者该分类下没有内容也是可以删除的。

创建外键的时候,如果你没有指定名字,系统会自动的帮你创建名字。

因为有外键的存在,父表是不让你删除的。

想把父表删除,必须保证父表分类下没有内容。

这时呢你就可以看到外键的名称是以你指定的名称创建的。

猜你喜欢

转载自blog.csdn.net/weixin_40316053/article/details/84196072