目录
一、引言
在数据库中,单表的增删改查都是最简单的,但是实际上可能会出现很多表,并且每张表之间都会存在一定的关系。比如:一对一、一对多、多对多、等表与表之间的常见的关系,下面会阐述如何区分上述关系并且在数据库中应用上述关系建表的技巧。
二、一对一关系
一对一关系指:表A与表B之间存在一一对应的关系,举例子:夫妻,一个丈夫对应一个妻子,每个人都有自己对应的信息,且丈夫和妻子是相对应的。即一一对应。
如下表:
其中每个人是一一对应的,一共有三种解决方法,将会一一阐述。
1.一对一融合表(优)
如果可以融合的话,则会减少一个表的容量,而且查询更加的简单,只需要单表查询,不需要多表查询。
单表查询:
select * from (表名) where (条件)
多表查询:
select (表名1).*,(表名2).* from (表名1),(表名2) where (表名1)和(表名2)相同的条件
由上述代码可知,单表查询更加的方便。
2.一对一连表查询(优)
在子表当中建立外键,外键为子父表之间联系的值,建立在子表当中。
在不可以融合表的情况下,推荐使用。
select (表名1).*,(表名2).* from (表名1),(表名2) where (表名1)和(表名2)相同的条件
3.一对一外建表查询
不改动两个表的情况下,新建一个表,用来存放表之间的关系。这样的情况,会新增一个表,使表之间的关系更加的复杂。
不推荐使用该情况。
4.总结
各种情况的优先级如下:
1.融合表(在情况允许的前提下)
2.连表查询 (子存放关系)
3.新建一个表用来存储两个表之间的关系
三、一对多关系
一对多关系指:表A与表B之间存在一对多应的关系,举例子:学生和班级,一个学生对应一个班级,而一个班级对应多个关系,每个学生都有自己对应的班级,因此是一对多关系。
如下表:
1.一对多融合表(不推荐)
思考一个问题,一对多的情况下,将子表和父表融合在一起的时候,子表会出现多个“计算机”和多个“大数据”等班级。在数据量非常庞大的情况下,则会造成非常严重的数据冗余。
数据冗余:一个字段在多个表里重复出现。
select (表名1).*,(表名2).* from (表名1),(表名2) where (表名1)和(表名2)相同的条件
因此不推荐使用该情况。
2.一对多连表查询(优)
已经知道一对多的融合表,不可取。
下面的情况,将班级的id值存到学生表中,可以解决数据冗余的问题,而且具有一定优势,且用连表查询或多表查询可以解决问题。
select (表名1).*,(表名2).* from (表名1),(表名2) where 表名1.class_id = 表名2.id
3.一对多外建表查询(不推荐)
新建一个表存放关系,不会造成数据冗余,但是会新建一个表,延缓查询速率,因此不推荐。
总结
推荐使用一对多连表查询,不使用前两种的情况。
四、多对多关系
多对多关系指:表A与表B之间存在多对多应的关系,举例子:学生和课程,一个学生可以对应多个课程,一个课程对应多个学生,因此是多对多关系。
如下表:
1.多对多融合表(非常不推荐)
和一对多的情况差不多,但是更加复杂,冗余量更加严重
多对多的情况下,将子表和父表融合在一起的时候,子表会出现多个“java”和多个“c”等班级。在数据量非常庞大的情况下,则会造成非常严重的数据冗余。
非常不推荐
2.多对多连表查询(不推荐)
多对多的情况下每一表中的每一份数据都对应另外一份表的多个数据,为了不出错,使用外键的情况下,也会出数据冗余的情况。
3.多对多外建表查询(推荐)
多对多的情况下,将有关系的值挑出来新建一张表,不会出现数据冗余。推荐使用:
4.总结
推荐使用:外建表查询
五、连表、多表查询
1.多表查询
select * from 表1 s1,表2 s2 where s1.cid = s2.id
select s1.*,classname 班级名 from 学生表 s1,班级表 s2 where s1.cid = s2.id
1.多表查询,相较于单表查询更加困难,语法困难,需要考虑的情况会很多。
2.多表查询会查询表与表之间共同的数据,单表之间多余的数据,不会被考虑在内。
多表查询:
select s1.*,classname 班级名 from 学生表 s1,班级表 s2 where s1.cid = s2.id
连表查询(内联表)
select s1.*,classname 班级名 from 学生表 s1 join 班级表 s2 on s1.cid = s2.id
上面的两种情况结果相同。
2.连表查询
1.内连接
select s1.*,classname 班级名 from 学生表 s1 join 班级表 s2 on s1.cid = s2.id
内连接查询的是左表和右表共同的部分。
2.左外连接
select s1.*,classname 班级名 from 学生表 s1 left join 班级表 s2 on s1.cid = s2.id
会查询出共同的部分,和左侧多出来的部分。
3.右外连接
select s1.*,classname 班级名 from 学生表 s1 rigth join 班级表 s2 on s1.cid = s2.id
会查询出共同的部分,和右侧多出来的部分。