一对多/多对一:
数据库设计分析:
案例:一个人可以拥有多辆汽车,要求查询出某人所拥有的所有汽车。
方案一:(差的设计-用一张表存储–数据冗余太严重)
编号 姓名 性别 年龄 汽车编号 车型 排量 价格 P001 Jack 男 25 C001 BMW 12L 80w P001 Jack 男 25 C002 Benz 12L 100w P001 Jack 男 25 C003 Benz 12L 100w P002 Tom 男 25 C004 BMW 12L 80w P002 Tom 男 25 C005 Benz 12L 100w P003 Rose 女 25 C006 Benz 12L 100w
方案二(好的设计):
1)把一方单独建个表
编号 姓名 性别 年龄 P001 Jack 男 25 P002 Tom 男 25 P003 Rose 女 25
2)把多方也建个表(依赖一方,通过外键–补一个字段)
外键:位于依赖一方,它是被依赖一方是主键
汽车编号 车型 排量 价格 车主 C001 BMW 12L 80w P001 C002 Benz 12L 100w P001 C003 Benz 12L 120w P001 C004 BMW 12L 80w P002 C005 Benz 12L 100w P002 C006 Benz 12L 100w P003
3)代码实现:
create table person2( id varchar(32) primary key, sname varchar(30), sex char(1), age int ); insert into person2 values('P1001','Jack','0',25); insert into person2 values('P1002','Tom','1',22); insert into person2 values('P1003','Rose','1',24); insert into person2 values('P1004','张三','0',25); create table car( id varchar(32) primary key, sname varchar(30), price numeric(10,2), /*numeric(a,b),a表示一共多少位数,b表示带有几位小数*/ pid varchar(32), /*为字段pid定义一个外键约束(来自person2表的字段id)*/ constraint car_fk foreign key(pid) references person2(id) ); insert into car values('C001','BMW',80.5,'P1001'); insert into car values('C002','Benz',100,'P1001'); insert into car values('C003','BMW',120.05,'P1001'); insert into car values('C004','Benz',88.5,'P1002'); insert into car values('C005','QQ',8.5,'P1002'); insert into car values('C006','BIKE',0.5,'P1003');
查询每个人拥有的车辆:
92年之前的写法:
select person2.sname as 车主,car.sname as 车辆 from person2,car where car.pid=person2.id;
现在的内关联写法:
select person2.sname as 车主 ,car.sname as 车辆 from person2 join car on car.pid=person2.id;
一对多和多对一是一样的!反过来理解就是了。
多对多:
数据库设计分析
案例:一个人可以选择多门课程,一门课程又可以被多人选择。
方案一:(差的设计–数据冗余太严重)
1)学生表
编号 姓名 性别 年龄 电话 ... P001 Jack 男 25 P002 Tom 男 25 P003 Rose 女 25
2)课程表
编号 名称 教材 学分... 学生 S001 Java ... ...... P001 S001 Java ... ...... P002 S001 Java ... ...... ... S002 数据库 ... ...... P001 S002 数据库 ... ...... P002
pass。
方案二(好的设计:两个实体表+一个关系表):
1)学生表(独立)—实体
编号 姓名 性别 年龄 电话 ... P001 Jack 男 25 P002 Tom 男 25 P003 Rose 女 25
2)课程表(独立)—实体
编号 名称 教材 学分... S001 Java ... ...... S002 数据库 ... ...... S003 XML ... ......
3)选课表(专为体现多对多的关系而新增的表)–关系
课程编号 学生编号 S001 P001 S001 P002 ... S002 P002 S002 P003 ... S003 P001 ... -------------- 外键 外键 | | | | --------- | 联合主键
4) 代码实现
create table stud( id varchar(32) primary key, sname varchar(30), age int ); create table ject( id varchar(32) primary key, sname varchar(30) ); create table sj( studid varchar(32), jectid varchar(32) ); /*单独添加约束,必须先添加联合主键,再添加外键*/ /*创建联合主键*/ alter table sj add constraint pk_sj primary key(studid,jectid); /*创建两个外键*/ alter table sj add constraint fk_stud foreign key(studid) references stud(id); alter table sj add constraint fk_ject foreign key(jectid) references ject(id);
如果需要删除外键
alter table sj drop foreign key fk_stud; alter table sj drop foreign key fk_ject;
初始化stud表数据
insert into stud values('P001','小花',25); insert into stud values('P002','Jack',23); insert into stud values('P003','Tom',24); insert into stud values('P004','张三',24); insert into stud values('P005','赵子龙',26);
初始化ject表:
insert into ject values('S001','Java'); insert into ject values('S002','JavaEE'); insert into ject values('S003','XML'); insert into ject values('S004','数据库'); insert into ject values('S005','JQuery');
初始化sj表:
insert into sj values('P001','S001'); insert into sj values('P001','S003'); insert into sj values('P002','S001'); insert into sj values('P002','S002'); insert into sj values('P002','S003'); insert into sj values('P003','S001'); insert into sj values('P004','S002'); insert into sj values('P004','S003');
关联(也称为连接):
左关联(left join) 右关联(right join) 内关联(inner join)
mysql不支持: 全关联(full join) 外关联(outter join)
可以把关联理解成:几个表合成一个新的表,然后在新表中进行查询!