1.一对一
比如一张表存储用户的用户名密码用以用户登录验证,一张表存储用户详细信息如:真实姓名,家庭住址等用以用户执行敏感操作时做验证。
user表
id | username | password |
1 | zhangsan | 123 |
2 | lisi | 123 |
user_info 表
id | realname | address |
1 | 张三 | 陕西 |
2 | 李四 | 山西 |
对于各种操作比如修改用户的真实姓名,如果在一张表可以:
update user_info set realname=*** where username=***
但还要写成:
update user_info set real_name=*** where id=(select id from user where username=***)
这两张表都是对同一个用户,一个用户提交给平台的信息一定是一一对应着,但是明明都是同一个用户的还这样设计表,尽管这样使每一个表的字段数量减少但也会因为增加表的数量使表的关系变得很乱,当设计一个简单表关系时这样也许不会怎样,但是表的数量一增加,表与表之间的关系就变得更加重要。所以设计表的时候尽可能让两个一对一的表合成一个表。
2.一对多(多对一)
这种设计用于一般对于像不复杂的关系,比如员工与老板之间的关系(一个员工受一个固定的老板管理,但一个老板管理多个员工)
employee表
id | name | employer_id |
1 | zhangsan | 1 |
2 | lisi | 1 |
3 | wangwu | 1 |
4 | tiegen | 2 |
employer表
id | name |
1 | 蔡徐坤 |
2 | 鸡哥 |
如果根据员工查询老板:
select name
from employer
join on employee
where employee.employer_id = employer.id
最后的结果就是一条信息
但是根据老板查询员工:
select name
from employee
join on employer
where employee.employer_id=employer.id
最后查询的结果就是多条数据
这里有注意点:
添加数据时先给主表添加数据(如老板表)添加数据,再给子表(如员工表),因为不可能没有老板就让员工上班。如果有可以给我介绍一下(dogo)
删除数据先删除子表数据,再删除主表数据,也不可能让老板直接离职,然后再给员工分配新的岗位.
3.多对多
这种数据库关系在像用户与角色之类的关系是基本一定会有的。
user 表
id | username |
1 | 坤坤 |
2 | kun |
3 | 菜虚困 |
4 | 鸡哥 |
role表
id | rolename |
1 | ikun |
2 | 小黑子 |
他们之间的关系可能如下图一样
他们之间会有复杂的关系,要表示他们之间的关系不能只使用两张表,因为如果user表中一个字段专门表示身份的话(或者role表的id)由于一个user可能有两个身份而sql又不能使用一个字段存取两个值;同理由于有很多user是某一个身份,也不能在role表使用一个字段映射到user。
这时就需要有一个中间表user_role
user_id | role_id |
1 | 1 |
1 | 2 |
2 | 1 |
3 | 1 |
3 | 2 |
4 | 1 |
来存储他们之间的关系
因为user表中没有任何与role表有关的字role表中没有任何与user表有关的字段,到时候使用查询语句就需要三个表关联。
比如查询kun的身份:
select rolename
from role r join user_role ur
on r.id=ur.role_id
join user u
on ur.user_id=(selec id
from user
where username=kun)