mysql中的第三范式
※多表操作 (凡是多表,都要用到关联技术(把多表合并成一个新表): 左关联、右关联、内关联。还有一个外(全)关联,MySQL不支持,为考虑软件兼容,我们开发一般不用。)
※表与表之间的关系:1对1,1对多,多对多
一、1对1
※第三范式: 1方建主表(id为主键字段), 多方建外键字段(husband--参考主表的主键id,加unique)
CREATE TABLE man(
id VARCHAR(32) PRIMARY KEY,
NAME VARCHAR(30)
);
CREATE TABLE woman(
id VARCHAR(32) PRIMARY KEY,
NAME VARCHAR(30),
husband VARCHAR(32) UNIQUE,
CONSTRAINT wm_fk FOREIGN KEY(husband) REFERENCES man(id)
);
//DROP TABLE woman;
INSERT INTO man VALUES('1','张三');
INSERT INTO man VALUES('2','李四');
INSERT INTO man VALUES('3','王五');
INSERT INTO woman VALUES('1','小花','1');
INSERT INTO woman VALUES('2','玉芬','3');
INSERT INTO woman VALUES('3','小玉','1');//Error:违反1对1
INSERT INTO woman VALUES('3','小玉','10');//Error:违反外键--主表必须存在该外键值
INSERT INTO man VALUES('10','王六');
INSERT INTO woman VALUES('3','小玉','10');//OK
//◇查询夫妻信息(内联)
SELECT man.name AS 丈夫, woman.name AS 妻子 FROM man
INNER JOIN woman ON man.id=woman.husband;
SELECT m.name AS 丈夫, w.name AS 妻子 FROM man AS m
INNER JOIN woman AS w ON m.id=w.husband;
二、1对多
※第三范式: 1方建主表(id为主键字段), 多方建外键字段(pid--参考主表的主键id,不加unique)
CREATE TABLE person2(
id VARCHAR(32) PRIMARY KEY,
NAME VARCHAR(30),
sex CHAR(1)
);
DROP TABLE car2;
CREATE TABLE car(
id VARCHAR(32) PRIMARY KEY,
NAME VARCHAR(30),
price NUMERIC(10,2),
pid VARCHAR(32),
CONSTRAINT car_fk FOREIGN KEY(pid) REFERENCES person2(id)
);
INSERT INTO person2 VALUES('P01','Jack','1');
INSERT INTO person2 VALUES('P02','Tom','1');
INSERT INTO person2 VALUES('P03','Rose','0');
INSERT INTO car VALUES('C001','BMW',30,'P01');
INSERT INTO car VALUES('C002','BEnZ',40,'P01');
INSERT INTO car VALUES('C003','Audi',40,'P01');
INSERT INTO car VALUES('C004','QQ',5.5,'P02');
//外键字段值可以为“NULL”
INSERT INTO car(id,NAME,price) VALUES('C005','ABC',10);
INSERT INTO car(id,NAME,price) VALUES('C006','BCD',10);
//◇查询哪些人有哪些车
SELECT * FROM car INNER JOIN person2 ON car.pid=person2.id;
SELECT car.NAME,car.price,person2.name FROM car
INNER JOIN person2 ON car.pid=person2.id ;
//◇查询Jack有哪些车
SELECT car.NAME,car.price,person2.name FROM car
INNER JOIN person2 ON car.pid=person2.id where person2.name='Jack';
//◇查询哪些人有两辆或两辆以上的车
//失败品:--每组只显示第一条
SELECT car.NAME,car.price,person2.name FROM car
INNER JOIN person2 ON car.pid=person2.id GROUP BY person2.id HAVING COUNT(car.pid)>=2;
//过渡版
SELECT car.NAME,car.price,person2.name FROM car
INNER JOIN person2 ON car.pid=person2.id WHERE person2.id IN('P01','P02');
SELECT pid FROM car GROUP BY pid HAVING COUNT(pid)>=2; //把上面写死的pid写成活的
//OK版
SELECT car.NAME,car.price,person2.name FROM car
INNER JOIN person2 ON car.pid=person2.id WHERE person2.id IN(
SELECT pid FROM car GROUP BY pid HAVING COUNT(pid)>=2
);
//演示左关联: SELECT * FROM person2 LEFT JOIN car ON car.pid=person2.id;
//◇查询哪些人没有车
SELECT person2.name FROM person2 LEFT JOIN car ON car.pid=person2.id
WHERE car.id IS NULL;
//◇补一个外键的概念(默认是约束): 删除主键信息时,当该主键字段值在外键表中存在时,该记录是不能删除的。---要把外键表是的相关信息删除之后,才能删除。 ---更新同理
DELETE FROM person2 WHERE id='P01';//car表中存在pid='P01'的车,所以主表不能删除'P01'这条记录
三、多对多( 3个表= 2个实体表 + 1个关系表 )
※第三范式: 两个实体都建成独立的主表, 另外再单独建一个关系表(采用联合主键)
1、分别建议两个实体表(没有外键,但有自己的主键, 没有冗余信息)
//DROP TABLE stud;
//学生表
CREATE TABLE stud(
id VARCHAR(32) PRIMARY KEY,
NAME VARCHAR(30)
);
//课程表
CREATE TABLE ject(
id VARCHAR(32) PRIMARY KEY,
NAME VARCHAR(30)
);
2、另外补建一个关系表
CREATE TABLE sj(
studid VARCHAR(32) NOT NULL,
jectid VARCHAR(32)
);
//注意,要先建联合主键,再添加外键。顺序不能反了。
ALTER TABLE sj ADD CONSTRAINT sj_pk PRIMARY KEY(studid,jectid);
ALTER TABLE sj ADD CONSTRAINT sj_fk1 FOREIGN KEY(studid) REFERENCES stud(id);
ALTER TABLE sj ADD CONSTRAINT sj_fk2 FOREIGN KEY(jectid) REFERENCES ject(id);
//删除外键约束
//ALTER TABLE sj DROP FOREIGN KEY sj_fk1;
//ALTER TABLE sj DROP FOREIGN KEY sj_fk2;
3、添加一些演示数据
//实体表1
INSERT INTO stud VALUES('S001','Jack');
INSERT INTO stud VALUES('S002','Rose');
INSERT INTO stud VALUES('S003','Tom');
//实体表2
INSERT INTO ject VALUES('J001','Java');
INSERT INTO ject VALUES('J002','Oracle');
INSERT INTO ject VALUES('J003','XML');
INSERT INTO ject VALUES('J004','JSP');
INSERT INTO ject VALUES('J005','Game');
//关系表
INSERT INTO sj VALUES('S001','J001');
INSERT INTO sj VALUES('S001','J003');
INSERT INTO sj VALUES('S001','J004');
INSERT INTO sj VALUES('S002','J002');
INSERT INTO sj VALUES('S002','J003');
INSERT INTO sj VALUES('S002','J004');
//查询哪些人选了哪些课
//SQL组织的1992标准,可用,但效率不高
SELECT stud.name, ject.NAME FROM stud,ject,sj WHERE stud.id=sj.studid AND ject.id=sj.jectid;
//SQL组织的1996标准,效率高,推荐使用---关联
SELECT stud.name, ject.NAME FROM stud INNER JOIN sj ON stud.id=sj.studid
INNER JOIN ject ON ject.id=sj.jectid;
//查询哪些人没选课
SELECT stud.name FROM stud LEFT JOIN sj ON stud.id=sj.studid
LEFT JOIN ject ON ject.id=sj.jectid where ject.id is NULL;
//查询哪些课没人选
SELECT ject.name FROM stud RIGHT JOIN sj ON stud.id=sj.studid
RIGHT JOIN ject ON ject.id=sj.jectid where stud.id is NULL;
--------------------------------------------------------------------------------------------
//额外补充:
1)在java中如果要对mysql进行操作时要导入mysql的jar包,倒入之后点右键中的bulid path进行导包;
2)外键可以保证两个表数据的一致性
mysql中的第三范式的更多相关文章
- 一、MySQL中的索引 二、MySQL中的函数 三、MySQL数据库的备份和恢复 四、数据库设计和优化(重点)
一.MySQL中的索引###<1>索引的概念 索引就是一种数据结构(高效获取数据),在mysql中以文件的方式存在.存储建立了索引列的地址或者指向. 文件 :(以某种数据 结构存放) 存放 ...
- MySQL中You can't specify target table for update in FROM clause一场
mysql中You can't specify target table <tbl> for update in FROM clause错误的意思是说,不能先select出同一表中的某些值 ...
- MySql中in和exists效率
mysql中的in语句是把外表和内表作hash 连接,而exists语句是对外表作loop循环,每次loop循环再对内表进行查询.一直大家都认为exists比in语句的效率要高,这种说法其实是不准确的 ...
- [原创]MYSQL中利用外键实现级联删除和更新
MySQL中利用外键实现级联删除.更新 MySQL支持外键的存储引擎只有InnoDB,在创建外键的时候,要求父表必须有对应的索引,子表在创建外键的时候也会自动创建对应的索引.在创建索引的时候,可以指定 ...
- mysql中的多行查询结果合并成一个
SELECT GROUP_CONCAT(md.data1) FROM DATA md,contacts cc WHERE md.conskey=cc.id AND md.mimetype_id= 5 ...
- 【转】MySql中的函数
原文:http://www.cnblogs.com/kissdodog/p/4168721.html MySQL数据库提供了很多函数包括: 数学函数: 字符串函数: 日期和时间函数: 条件判断函数: ...
- sqlserver 中数据导入到mysql中的方法以及注意事项
数据导入从sql server 到mysql (将数据以文本格式从sqlserver中导出,注意编码格式,再将文本文件导入mysql中): 1.若从slqserver中导出的表中不包含中文采用: bc ...
- MySQL中有关TIMESTAMP和DATETIME的总结
一.MySQL中如何表示当前时间? 其实,表达方式还是蛮多的,汇总如下: CURRENT_TIMESTAMP CURRENT_TIMESTAMP() NOW() LOCALTIME LOCALTIME ...
- MySQL中索引和优化的用法总结
1.什么是数据库中的索引?索引有什么作用? 引入索引的目的是为了加快查询速度.如果数据量很大,大的查询要从硬盘加载数据到内存当中. 2.InnoDB中的索引原理是怎么样的? InnoDB是Mysql的 ...
随机推荐
- UVA 10585 Center of symmetry
题意:给出一个点集,问这个集合有没有中心点使点集对称,这个点可以是点集中的点也可以不是点集的点. 解法:一开始我枚举每两个点连线的中点……结果T了orz当时也不知道怎么想的…… 将点按横坐标排序,如果 ...
- c#操作XML文件的通用方法
转载地址:http://www.studyofnet.com/news/36.html 原址没找到 sing System; using System.Data; using System.Confi ...
- javscript面试题(一)
你如何理解HTML结构的语意化? 1.去掉或样式丢失的时候能让页面呈现清晰的结构:2.屏幕阅读器(如果访客有视障)会完全根据你的标记来“读”你的网页:3.PDA.手机等设备可能无法像普通电脑的浏览器一 ...
- TCP服务端和客户端的框架
提供一个框架服务器端: 创建一个Socket sFd=socket(AF_INET,SOCK_STREAM,0) 把Socket和本机的IP,TCP口绑定 bind(sFd,(structsockad ...
- Android编译过程详解(一)
Android编译过程详解(一) 注:本文转载自Android编译过程详解(一):http://www.cnblogs.com/mr-raptor/archive/2012/06/07/2540359 ...
- 7.OpenACC
OpenACC: openacc 可以用于fortran, c 和 c++程序,可以运行在CPU或者GPU设备. openacc的代码就是在原有的C语言基础上进行修改,通过添加:compiler di ...
- Bnuoj-29359 Deal with numbers 线段树
题目链接:http://www.bnuoj.com/bnuoj/problem_show.php?pid=29359 题意:一个数列,有三种操作: 1.区间[a,b]之间大于零的数整出c. 2.区间[ ...
- Win7旗舰版的nfs服务器如何架设? - Microsoft Community
Win7旗舰版的nfs服务器如何架设? - Microsoft Community Win7旗舰版的nfs服务器如何架设?
- mac linux netstat -n
一直都不明白为什么mac就是不现实8080端口,现在明白了 USERtekiiMac-3:~ user$ netstat -an | grep tcp46 tcp46 0 0 *.8009 *.* L ...
- flashback data archive (转)
闪回数据归档(Flashback Data Archive) 在Oracle 11g当中,对闪回技术再次进行了扩展,提供了一个全新的flashback方式,称之为闪回数据归档,本节我们将对闪回数据归档 ...