※多表操作 (凡是多表,都要用到关联技术(把多表合并成一个新表): 左关联、右关联、内关联。还有一个外(全)关联,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中的第三范式的更多相关文章

  1. 一、MySQL中的索引 二、MySQL中的函数 三、MySQL数据库的备份和恢复 四、数据库设计和优化(重点)

    一.MySQL中的索引###<1>索引的概念 索引就是一种数据结构(高效获取数据),在mysql中以文件的方式存在.存储建立了索引列的地址或者指向. 文件 :(以某种数据 结构存放) 存放 ...

  2. 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出同一表中的某些值 ...

  3. MySql中in和exists效率

    mysql中的in语句是把外表和内表作hash 连接,而exists语句是对外表作loop循环,每次loop循环再对内表进行查询.一直大家都认为exists比in语句的效率要高,这种说法其实是不准确的 ...

  4. [原创]MYSQL中利用外键实现级联删除和更新

    MySQL中利用外键实现级联删除.更新 MySQL支持外键的存储引擎只有InnoDB,在创建外键的时候,要求父表必须有对应的索引,子表在创建外键的时候也会自动创建对应的索引.在创建索引的时候,可以指定 ...

  5. mysql中的多行查询结果合并成一个

    SELECT GROUP_CONCAT(md.data1) FROM DATA md,contacts cc WHERE md.conskey=cc.id AND md.mimetype_id= 5 ...

  6. 【转】MySql中的函数

    原文:http://www.cnblogs.com/kissdodog/p/4168721.html MySQL数据库提供了很多函数包括: 数学函数: 字符串函数: 日期和时间函数: 条件判断函数: ...

  7. sqlserver 中数据导入到mysql中的方法以及注意事项

    数据导入从sql server 到mysql (将数据以文本格式从sqlserver中导出,注意编码格式,再将文本文件导入mysql中): 1.若从slqserver中导出的表中不包含中文采用: bc ...

  8. MySQL中有关TIMESTAMP和DATETIME的总结

    一.MySQL中如何表示当前时间? 其实,表达方式还是蛮多的,汇总如下: CURRENT_TIMESTAMP CURRENT_TIMESTAMP() NOW() LOCALTIME LOCALTIME ...

  9. MySQL中索引和优化的用法总结

    1.什么是数据库中的索引?索引有什么作用? 引入索引的目的是为了加快查询速度.如果数据量很大,大的查询要从硬盘加载数据到内存当中. 2.InnoDB中的索引原理是怎么样的? InnoDB是Mysql的 ...

随机推荐

  1. 从ramdisk根文件系统启动Linux 二

    今天做了个试验,让Linux2.6.29.4从ramdisk根文件系统启动成功,总结一下.其中涉及的内容较多,很多东西不再详述,如需深入研究请查阅相关资料(百度或谷歌一下一大堆). 开发环境:Fedo ...

  2. MSP430 flash的操作

    今天顺便研究了一下msp430的flash操作,很多人也许看了我的博客,会发现网站上有很多的人总结得比我要好,这点我承认,因为自己能力有限,但是,从这篇博客起,我会参照以前大神们写的博客,添加大神们写 ...

  3. [娱乐]GameMaker绘制参数方程的图像

    今天,我翻了旧物,硬着头皮看了这源码.突然恍然大悟,这岂不就是当年学的参数方程! 目前,最早开始教授参数方程实在高三时,并作为一门选修课程,简化了求解圆锥曲线方程的难度,在高考中也很容易拿分,考试过后 ...

  4. 设计模式_Composite_合成模式

    形象例子: Mary今天过生日.“我过生日,你要送我一件礼物.”“嗯,好吧,去 商店,你自己挑.”“这件T恤挺漂亮,买,这条裙子好看,买,这个包也不错,买.”“喂,买了三件了呀,我只答应送一件礼物的哦 ...

  5. Android编译过程详解(一)

    Android编译过程详解(一) 注:本文转载自Android编译过程详解(一):http://www.cnblogs.com/mr-raptor/archive/2012/06/07/2540359 ...

  6. Hander

    多线程与UI线程间通信 向你展示如何从任务发送数据对象上运行用户界面(UI)线程.该特性允许你的任务做背景的工作结果,然后再到UI元素如位图. 每个应用程序都有自己的特殊的线程运行的UI对象如视图对象 ...

  7. HDU-1402 A * B Problem Plus FFT(快速傅立叶变化)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1402 一般的的大数乘法都是直接模拟乘法演算过程,复杂度O(n^2),对于这题来说会超时.乘法的过程基本 ...

  8. 关于 Java Collections API 您不知道的 5 件事,第 1 部分

    定制和扩展 Java Collections Java™ Collections API 远不止是数组的替代品,虽然一开始这样用也不错.Ted Neward 提供了关于用 Collections 做更 ...

  9. 搭建Discuz! (mysql+apache+Discuz! )

    0. 配置环境 0.0 安装apache 0.1 安装php 1.数据库准备 1.1 创建数据库用户 1.2 创建discuz使用的数据库(编码:utf8-general-ci) 1.3 把1.2创建 ...

  10. .NET设计模式(1):开篇

    转载:http://terrylee.cnblogs.com/archive/2005/12/09/293465.html .NET设计模式开篇 --.NET设计模式系列之一 Terrylee,200 ...