详解 MySQL 数据库连接

引言

上次博文引用了各连接的示意图,未做详述,本文补充对数据库各连接的实例描述。

image.png

举个栗子

数据

数据为klassstudent的关系,班级一对多学生,没有加外键。

image.png

image.png

数据关系如下:1班的Hello Kitty和史努比,2班的米老鼠和唐老鸭,3班没学生,葫芦娃没有班级。

image.png

何为连接?

关系型数据库,即数据之间是有所关系的。

就如我们当前场景下的klassstudent表一样,两表中的数据在实际的业务场景中是有所关联的,学生属于哪个班级,这种多对一的关系,我们在学生表中加上klass_id一列存储这种关系。

班级与学生的关系通过klass_id进行维护。

简单的单表查询:

SELECT *
FROM `klass`;

image.png

如果想同时看教师和班级的数据,就需要进行多表查询了:

SELECT `klass`.`name` as `klass_name`, `student`.`name` as `student_name`
FROM `klass`, `student`
WHERE `klass`.`id` = `student`.`klass_id`;

image.png

How it works?

进行多表查询时,其实是将两表的记录先做笛卡尔积,再根据WHERE条件对数据进行过滤。

不加WHERE条件的示例:

SELECT `klass`.`name` as `klass_name`, `student`.`name` as `student_name`
FROM `klass`, `student`;

image.png

很惭愧,从我学数据库到现在,每次我手写这样需求的SQL,都是使用的这种方法进行多表查询。

Better?

试想,如果我们所有的多表查询,都使用WHERE进行过滤,这会造成一个很严重的问题。

如果查询条件很复杂的话,会导致WHERE语句不仅充斥着数据表层面的连接条件,还充斥着各种业务条件,会让WHERE语句很不直观。

SELECT `klass`.`name` as `klass_name`, `student`.`name` as `student_name`
FROM `klass`, `student`
WHERE `klass`.`id` = `student`.`klass_id`;

参考问题:INNER JOIN ON vs WHERE clause - StackOverflow

这种场景下推荐使用内连接代替WHERE

内连接可更好地完成上述需求:

SELECT `klass`.`name` as `klass_name`, `student`.`name` as `student_name`
FROM `klass`
INNER JOIN `student`
ON `klass`.`id` = `student`.`klass_id`;

image.png

并且,连接的条件写在ON里,WHERE只写业务条件,更直观。

image.png

左连接/右连接

内连接:内连接基于连接谓词将两张表(如 AB )的列组合在一起,产生新的结果表。查询会将 A 表的每一行和 B 表的每一行进行比较,并找出满足连接谓词的组合。当连接谓词被满足,AB 中匹配的行会按列组合(并排组合)成结果集中的一行。

示例数据有三个班,但是3班因为没有任何学生与之关联,所以不符合查询谓语中的klass.id = student.klass_id,所以没有3班的信息。

同样地,因为学生“葫芦娃”没有班级,也不符合查询条件,同样没有出现在内连接的查询 结果中。

注:在表连接中NULL != NULL

image.png

如果想让数据显示完全,就需要左连接与右连接了。

image.png

klass表连接student表,klass算左表,student算右表。

左连接,显示左表所有数据:

SELECT `klass`.`name` as `klass_name`, `student`.`name` as `student_name`
FROM `klass`
LEFT JOIN `student`
ON `klass`.`id` = `student`.`klass_id`;

3班在左连接中出现了:

image.png

右连接,显示右表所有数据:

SELECT `klass`.`name` as `klass_name`, `student`.`name` as `student_name`
FROM `klass`
RIGHT JOIN `student`
ON `klass`.`id` = `student`.`klass_id`;

“葫芦娃”在右连接中出现了:

image.png

总结

宝剑锋从磨砺出,梅花香自苦寒来。
阅读 387

推荐阅读
Tomorrow
用户专栏

明天,你好

316 人关注
136 篇文章
专栏主页