每张表都有对应的主键“id”对这个表中的数据进行唯一定位,那表与表之间的关联就可以通过对应的主键id去展开这条信息对应另外一张表的信息。
数据库的表与表之间应该是相互关联的。
关联表创建
公共表
班级表:common_class
mysql> select * from common_class;
+----------+-------------+
| class_id | vname |
+----------+-------------+
| 1 | Class_one |
| 2 | Class_two |
| 3 | Class_three |
+----------+-------------+
3 rows in set
课程表:common_courses
mysql> select * from common_courses;
+-----+-------------+
| cid | vname |
+-----+-------------+
| 1 | Mathematics |
| 2 | Science |
| 3 | History |
| 4 | Philosophy |
+-----+-------------+
4 rows in set
关联表
学生班级表:zx_users_info
mysql> desc zx_users_info;
+----------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| uid | int(10) unsigned | YES | | NULL | |
| class_id | int(10) unsigned | YES | | NULL | |
+----------+------------------+------+-----+---------+----------------+
3 rows in set
学生选课表:users_courses
mysql> desc users_courses;
+------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| courses_id | int(10) unsigned | NO | | NULL | |
| uid | int(10) unsigned | NO | | NULL | |
+------------+------------------+------+-----+---------+----------------+
3 rows in set
表:一对一的关联
在一张表中,表的一条信息对应另一张表的一条消息,并且双方对应的键值不能重复。
用户信息表:zx_users_info存学生id字段uid。
根据最小授权原则,将学生id放入zx_users_info表中,维护学生信息的管理员不需要知道用户名之外的信息,例如密码信息,因此也不需要在zx_users表中添加额外无关的字段。
通过用select查学生user2的信息为:
mysql> select id from zx_users where vname = 'user2';
+----+
| id |
+----+
| 3 |
+----+
1 row in set
mysql> select * from zx_users_info where uid = 3;
+----+-----+----------+
| id | uid | class_id |
+----+-----+----------+
| 1 | 3 | 1 |
+----+-----+----------+
1 row in set
由于表与表之间是通过键值关联,zx_users_info添加了uid字段,关联表zx_users,想要知道学生user2在zx_users_info上的信息,必须先通过user2这个名字在zx_users查找到该学生对应的id字段。
由于键值的不公开性,前端只能通过users2这个名字去关联其他表,一一对应查找这个学生的其他信息。因此需要通过表的关联才能做到。
SQL命令:
mysql> select zx_users_info.*
from zx_users,zx_users_info
where
zx_users.vname = 'user2'
and
zx_users_info.uid = zx_users.id;
+----+-----+----------+
| id | uid | class_id |
+----+-----+----------+
| 1 | 3 | 1 |
+----+-----+----------+
1 row in set
由于zx_users和zx_users_info在命令中出现过多次,可以通过省略缩写:
zx_users :t(to)
zx_users_info :f(from)
SQL命令:
mysql> select f.*
from zx_users t,zx_users_info f
where
t.vname = 'user2'
and
f.uid = t.id;
+----+-----+----------+
| id | uid | class_id |
+----+-----+----------+
| 1 | 3 | 1 |
+----+-----+----------+
1 row in set
表:一对多的关联
在一张表中,表的一条信息对应另一张表的多条消息,并且该表对应的键值不能重复,另一张表对应的键值可以重复。
用户信息表:zx_users_info存着用户的班级信息字段class_id。
zx_users_info一一对应每个学生的id,但一个班级可以包括多个学生,因此class_id的内容可以相同。
通过用select查单个学生user2的班级信息
SQL命令:
mysql> select ct.vname
from zx_users ut,zx_users_info uit,common_class ct
where
ut.vname = 'user2'
and
uit.uid = ut.id
and
ct.class_id = uit.class_id;
+-----------+
| vname |
+-----------+
| Class_one |
+-----------+
1 row in set
通过班级名字查该班级的学生信息
SQL命令:
mysql> select vname from zx_users where id = any(
select zx_users_info.uid
from zx_users_info
where zx_users_info.class_id = (
select class_id
from common_class
where vname = 'Class_one'
)
);
+---------+
| vname |
+---------+
| user2 |
| userpwd |
| userpwd |
| userpwd |
+---------+
4 rows in set
表:多对多的关联
在一张表中,表的多条信息对应另一张表的多条消息,并且双方对应的键值可以重复。
课程表:users_courses包含学生的选课信息,一个学生可以选择多门课,同样一门课程可以容纳多名学生。
通过用select查单个学生user2的选课情况:
MySQL命令
mysql> select vname from common_courses where cid = any(
select f.courses_id
from zx_users t,users_courses f
where t.vname = 'user2'
and
f.uid = t.id
);
+-------------+
| vname |
+-------------+
| Mathematics |
| Science |
| Philosophy |
+-------------+
3 rows in set
通过用select查单个课程Mathematics的学生选课情况:
MySQL命令
mysql> select vname from zx_users where id = any(
select f.uid
from common_courses t,users_courses f
where t.vname = 'Mathematics'
and
f.courses_id = t.cid
);
+---------+
| vname |
+---------+
| user1 |
| user2 |
| userpwd |
| userpwd |
+---------+
4 rows in set