多表关系
在实际项目开发的时候可能设计到多张表,表与表之间存在一定关系,如何设计表之间的关系让系统更加优化,需要考虑到多表之间关系。
1. 一对一(了解)* 如:人和身份证* 分析:一个人只有一个身份证,一个身份证只能对应一个人2. 一对多(多对一)* 如:部门和员工* 分析:一个部门有多个员工,一个员工只能对应一个部门3. 多对多* 如:学生和课程* 分析:一个学生可以选择很多门课程,一个课程也可以被很多学生选择
一对一关系
一个人有一个身份证号码,一个身份证号码只对应一个人
-- 创建身份证表CREATE TABLE card(id INT PRIMARY KEY,number VARCHAR(18));-- 设置身份证号码唯一ALTER TABLE card MODIFY number VARCHAR(20) UNIQUE;INSERT INTO card(id,number) VALUES(1,420923199211090512);INSERT INTO card(id,number) VALUES(2,420923199310230807);INSERT INTO card(id,number) VALUES(3,420923199007080908);-- 创建人员表CREATE TABLE person(id INT PRIMARY KEY,NAME VARCHAR(20),cid INT);-- 给人员表添加外键ALTER TABLE person ADD CONSTRAINT cid_kf FOREIGN KEY(cid) REFERENCES card(id);-- 设置外键唯一ALTER TABLE person MODIFY cid INT UNIQUE;-- 向person表中添加数据INSERT INTO person(id,NAME,cid) VALUES(1,"张三",1);INSERT INTO person(id,NAME,cid) VALUES(2,"李四",2);INSERT INTO person(id,NAME,cid) VALUES(3,"王五",3);
一对多关系
一个部门可以有多个员工,一个员工只能对应一个部门
-- 创建部门表(主表)CREATE TABLE department(id INT PRIMARY KEY,NAME VARCHAR(20));-- 向部门表中添加数据INSERT INTO department(id,NAME) VALUES(1,"教研部");INSERT INTO department(id,NAME) VALUES(2,"学工部");INSERT INTO department(id,NAME) VALUES(3,"就业部");SELECT * FROM department;-- 创建员工表(从表)CREATE TABLE employee(id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(20) NOT NULL,age INT,dep_id INT,CONSTRAINT emp_depid_fk FOREIGN KEY(dep_id) REFERENCES department(id));-- 向员工表中添加数据INSERT INTO employee(NAME,age,dep_id) VALUES("张三",18,1);INSERT INTO employee(NAME,age,dep_id) VALUES("李四",20,2);INSERT INTO employee(NAME,age,dep_id) VALUES("王五",21,1);INSERT INTO employee(NAME,age,dep_id) VALUES("赵六",19,3);INSERT INTO employee(NAME,age,dep_id) VALUES("田七",24,2);INSERT INTO employee(NAME,age,dep_id) VALUES("周八",23,3);INSERT INTO employee(NAME,age,dep_id) VALUES("黄九",25,1);SELECT * FROM employee;
多对多关系
一个学生可以选择很多门课程,一个课程也可以被很多学生选择
-- 创建学生表CREATE TABLE student(sid INT PRIMARY KEY,NAME VARCHAR(20),age INT);INSERT INTO student(sid,NAME,age) VALUES(1,"张三",20);INSERT INTO student(sid,NAME,age) VALUES(2,"李四",19);INSERT INTO student(sid,NAME,age) VALUES(3,"王五",18);INSERT INTO student(sid,NAME,age) VALUES(4,"赵六",21);INSERT INTO student(sid,NAME,age) VALUES(5,"田七",24);INSERT INTO student(sid,NAME,age) VALUES(6,"周八",23);-- 创建课程表CREATE TABLE class(cid INT PRIMARY KEY,NAME VARCHAR(20));INSERT INTO class(cid,NAME) VALUES(1,"Java基础");INSERT INTO class(cid,NAME) VALUES(2,"HTML");INSERT INTO class(cid,NAME) VALUES(3,"Javascript");INSERT INTO class(cid,NAME) VALUES(4,"mysql");-- 创建外键表CREATE TABLE foreign_table(sid INT,cid INT,CONSTRAINT sid_fk FOREIGN KEY(sid) REFERENCES student(sid), -- 外键sid 关联 student sid主键CONSTRAINT cid_fk FOREIGN KEY(cid) REFERENCES class(cid) -- 外键cid 关联 class cid主键);INSERT INTO foreign_table(sid,cid) VALUES(1,1);INSERT INTO foreign_table(sid,cid) VALUES(1,2);INSERT INTO foreign_table(sid,cid) VALUES(1,3);INSERT INTO foreign_table(sid,cid) VALUES(1,4);INSERT INTO foreign_table(sid,cid) VALUES(2,1);INSERT INTO foreign_table(sid,cid) VALUES(2,2);INSERT INTO foreign_table(sid,cid) VALUES(3,4);INSERT INTO foreign_table(sid,cid) VALUES(3,1);
多表查询
准备数据
-- 创建db4数据库CREATE DATABASE db4;-- 使用db4数据库USE db4;-- 创建user表CREATE TABLE USER(id INT PRIMARY KEY AUTO_INCREMENT, -- 用户idNAME VARCHAR(20), -- 用户姓名age INT -- 用户年龄);-- 添加数据INSERT INTO USER VALUES (1,'张三',23);INSERT INTO USER VALUES (2,'李四',24);INSERT INTO USER VALUES (3,'王五',25);INSERT INTO USER VALUES (4,'赵六',26);-- 订单表CREATE TABLE orderlist(id INT PRIMARY KEY AUTO_INCREMENT, -- 订单idnumber VARCHAR(30), -- 订单编号uid INT, -- 外键字段CONSTRAINT ou_fk1 FOREIGN KEY (uid) REFERENCES USER(id));-- 添加数据INSERT INTO orderlist VALUES (1,'hm001',1);INSERT INTO orderlist VALUES (2,'hm002',1);INSERT INTO orderlist VALUES (3,'hm003',2);INSERT INTO orderlist VALUES (4,'hm004',2);INSERT INTO orderlist VALUES (5,'hm005',3);INSERT INTO orderlist VALUES (6,'hm006',3);INSERT INTO orderlist VALUES (7,'hm007',NULL);-- 商品分类表CREATE TABLE category(id INT PRIMARY KEY AUTO_INCREMENT, -- 商品分类idNAME VARCHAR(10) -- 商品分类名称);-- 添加数据INSERT INTO category VALUES (1,'手机数码');INSERT INTO category VALUES (2,'电脑办公');INSERT INTO category VALUES (3,'烟酒茶糖');INSERT INTO category VALUES (4,'鞋靴箱包');-- 商品表CREATE TABLE product(id INT PRIMARY KEY AUTO_INCREMENT, -- 商品idNAME VARCHAR(30), -- 商品名称cid INT, -- 外键字段CONSTRAINT cp_fk1 FOREIGN KEY (cid) REFERENCES category(id));-- 添加数据INSERT INTO product VALUES (1,'华为手机',1);INSERT INTO product VALUES (2,'小米手机',1);INSERT INTO product VALUES (3,'联想电脑',2);INSERT INTO product VALUES (4,'苹果电脑',2);INSERT INTO product VALUES (5,'中华香烟',3);INSERT INTO product VALUES (6,'玉溪香烟',3);INSERT INTO product VALUES (7,'计生用品',NULL);-- 中间表CREATE TABLE us_pro(upid INT PRIMARY KEY AUTO_INCREMENT, -- 中间表iduid INT, -- 外键字段。需要和用户表的主键产生关联pid INT, -- 外键字段。需要和商品表的主键产生关联CONSTRAINT up_fk1 FOREIGN KEY (uid) REFERENCES USER(id),CONSTRAINT up_fk2 FOREIGN KEY (pid) REFERENCES product(id));-- 添加数据INSERT INTO us_pro VALUES (NULL,1,1);INSERT INTO us_pro VALUES (NULL,1,2);INSERT INTO us_pro VALUES (NULL,1,3);INSERT INTO us_pro VALUES (NULL,1,4);INSERT INTO us_pro VALUES (NULL,1,5);INSERT INTO us_pro VALUES (NULL,1,6);INSERT INTO us_pro VALUES (NULL,1,7);INSERT INTO us_pro VALUES (NULL,2,1);INSERT INTO us_pro VALUES (NULL,2,2);INSERT INTO us_pro VALUES (NULL,2,3);INSERT INTO us_pro VALUES (NULL,2,4);INSERT INTO us_pro VALUES (NULL,2,5);INSERT INTO us_pro VALUES (NULL,2,6);INSERT INTO us_pro VALUES (NULL,2,7);INSERT INTO us_pro VALUES (NULL,3,1);INSERT INTO us_pro VALUES (NULL,3,2);INSERT INTO us_pro VALUES (NULL,3,3);INSERT INTO us_pro VALUES (NULL,3,4);INSERT INTO us_pro VALUES (NULL,3,5);INSERT INTO us_pro VALUES (NULL,3,6);INSERT INTO us_pro VALUES (NULL,3,7);INSERT INTO us_pro VALUES (NULL,4,1);INSERT INTO us_pro VALUES (NULL,4,2);INSERT INTO us_pro VALUES (NULL,4,3);INSERT INTO us_pro VALUES (NULL,4,4);INSERT INTO us_pro VALUES (NULL,4,5);INSERT INTO us_pro VALUES (NULL,4,6);INSERT INTO us_pro VALUES (NULL,4,7);
内连接查询
- 内连接查询语法
- 内连接查询是查询两个表有交集的部分
-- 显示内连接查询SELECT 列名 FROM 表名1 [INNER] JOIN 表名2 ON 关联条件;-- 隐式内连接查询SELECT 列名 FROM 表名1,表名2 WHERE 关联条件;
- 内连接查询举例
-- 查询用户信息和对应的订单信息select *from user inner join orderlist on orderlist.uid = user.id;-- 查询用户信息和对应的订单信息,起别名select * from user u inner join orderlist o on o.uid=u.id;-- 查询用户姓名,年龄。和订单编号select u.name,u.age,o.number from user u inner join orderlist o on o.uid=u.id;
外连接查询
- 外连接查询语法
-- 左外连接查询:查询原理:查询左表的全部数据,和左右两张表有交集的部分SELECT 列名 FROM 表名1 LEFT [OUTER] JOIN 表名2 ON 条件;-- 右外连接查询查询原理:查询右表的全部数据,和左右两张表有交集的部分SELECT 列名 FROM 表名1 RIGHT [OUTER] JOIN 表名2 ON 条件;
- 外连接查询举例
-- 查询所有用户信息,以及用户对应的订单信息SELECTu.*,o.numberFROMUSER uLEFT OUTER JOINorderlist oONo.uid=u.id;-- 查询所有订单信息,以及订单所属的用户信息SELECTu.*,o.numberFROMUSER uRIGHT OUTER JOINorderlist oONo.uid=u.id;
子查询
子查询就是利用SQL语句的查询结果,再结合其他SQL条件再次进行查询。
- 子查询的结果是一行一列
子查询的结果是一行一列,可以将子查询的结果当做某一个字段的值,作为where子句的条件;
select 列名 from 表名 where 列名=(select 列名 from 表名[where 条件]);-- 查询用户最大的年龄SELECT MAX(age) FROM USER;-- 查询年龄最大的用户姓名select name ,age from user where age=(select max(age) from user);
- 子查询的结果是多行单列
子查询的结果是多行单列,可以将子查询的结果当做某一个字段的多个值,作为where子句的条件。
可以作为条件,使用运算符in或not in来进行判断。select 列名 from 表名 where 列名 [not]in(select 列名 表名 [where 条件]);-- 查询张三和李四的idselect id from user where name in('张三','李四');-- 查询张三和李四的订单信息select * from orderlist where uid in (select id from user where name in('张三','李四'));
- 子查询的结果是多行多列
子查询的结果是多行多列,可以将子查询的结果当做一个虚拟表来看待,并和其他表进行连接查询。
select 列名 from 表名,(select 列名 from 表名[where 条件])[where 条件];-- 查询订单表中id>4的订单信息select * from orderlist where id>4;-- 查询订单表中id大于4的订单信息和所属用户信息select u.name,o.number from user u ,(select * from orderlist where id>4) o where o.uid=u.id;
自关联查询
- 准备数据
-- 创建员工表CREATE TABLE employee(id INT PRIMARY KEY AUTO_INCREMENT, -- 员工编号NAME VARCHAR(20), -- 员工姓名mgr INT, -- 上级编号salary DOUBLE -- 员工工资);-- 添加数据INSERT INTO employee VALUES (1001,'孙悟空',1005,9000.00),(1002,'猪八戒',1005,8000.00),(1003,'沙和尚',1005,8500.00),(1004,'小白龙',1005,7900.00),(1005,'唐僧',NULL,15000.00),(1006,'武松',1009,7600.00),(1007,'李逵',1009,7400.00),(1008,'林冲',1009,8100.00),(1009,'宋江',NULL,16000.00);
-- 查询所有员工的姓名及其直接上级的姓名,没有上级的员工也需要查询/*分析员工信息 employee表条件:employee.mgr = employee.id查询左表的全部数据,和左右两张表有交集部分数据,左外连接*/SELECTe1.id,e1.name,e1.mgr,e2.id,e2.nameFROMemployee e1LEFT OUTER JOINemployee e2ONe1.mgr = e2.id;
多表查询练习
- 查询用户的编号、姓名、年龄。订单编号
/*分析:查询的表:用户表(user),订单表(orderlist)查询的字段:用户编号,姓名,年龄,订单编号查询的条件:user.id=orderlist.uid*/selectu.id,u.name,u.age,o.numberfromuser u,orderlist owhereu.id=o.uid;
- 查询所有的用户。用户的编号、姓名、年龄。订单编号
/*分析:查询的表:用户表(user),订单表(orderlist)。 所有用户,左外连接查询的字段:用户编号,姓名,年龄,订单编号查询的条件:orderlist.uid = user.id*/selectu.id,u.name,u.age,o.numberfromuser uleft joinorderlist oonu.id=o.uid;
- 查询所有的订单。用户的编号、姓名、年龄。订单编号
/*分析:查询的表:用户表(user),订单表(orderlist)。所有订单,忧外连接查询的字段:用户的编号、姓名、年龄、订单编号查询的条件:orderlist.uid = user.id*/selectu.id,u.name,u.age,o.numberfromuser uright joinorderlist oono.uid=u.id;
- 查询用户年龄大于23岁的信息。显示用户的编号、姓名、年龄。订单编号
/*分析:查询的表:用户表(user),订单表(orderlist)查询的字段:用户的编号、姓名、年龄。订单编号查询的条件:user.id=orderlist.uid and user.age>23*/selectu.id,u.name,u.age,o.numberfromuser u,orderlist owhereu.id=o.uid and u.age>23;
- 查询张三和李四用户的信息。显示用户的编号、姓名、年龄。订单编号
/*分析:查询的表:用户表(user),订单表(orderlist)查询的字段:显示用户的编号、姓名、年龄。订单编号查询的条件:user.name in ("张三","李四") and user.id=orderlist.uid;*/selectu.id,u.name,u.age,o.numberfromuser u,orderlist owhereu.id=o.uid and u.name in ("张三","李四");
- 查询商品分类的编号、分类名称。分类下的商品名称
/*分析:查询的表:商品表(product)、分类表(category)查询的字段:商品分类的编号、分类名称、商品名称查询的条件:product.cid=category.id*/selectc.id,c.name,p.namefromproduct p,category cwherep.cid=c.id;
- 查询所有的商品分类。商品分类的编号、分类名称。分类下的商品名称
/*分析:查询的表:商品表(product)、分类表(category)查询的字段:商品分类的编号(id)、分类名称(name)、商品名称(name)查询的条件:product.cid=category.id*/selectc.id,c.name,p.namefromproduct pright joincategory conp.cid=c.id;
- 查询所有的商品信息。商品分类的编号、分类名称。分类下的商品名称
/*分析:查询的表:商品表(product)、分类表(category)查询的字段:商品分类的编号(id)、分类名称(name)、商品名称(name)查询的条件:product.cid=category.id*/selectc.id,c.name,p.namefromproduct pleft joincategory conp.cid=c.id;
- 查询所有的用户和该用户能查看的所有的商品。显示用户的编号、姓名、年龄。商品名称
/*分析:查询的表:用户表(user),商品表(product),中间表(us_pro)查询的字段:用户的编号、姓名、年龄。商品名称查询的条件:user.id=us_pro.uid and product.id=us_pro.pid;*/selectu.id,u.name,u.age,p.namefromuser u,product p,us_pro upwhereu.id=up.uid and p.id=up.pid;
- 查询张三和李四这两个用户可以看到的商品。显示用户的编号、姓名、年龄。商品名称
/*分析:查询的表:用户表(user),商品表(product),中间表(us_pro)查询的字段:用户的编号、姓名、年龄。商品名称查询的条件:user.name in ("张三","李四")and us_pro.uid=user.id;and us_pro.pid=product.id;*/selectu.id,u.name,u.age,p.namefromuser u,product p,us_pro upwhereu.name in ("张三","李四") and up.uid=u.id and up.pid=p.id;
视图操作
视图(view)是一种虚拟存在的表,本身并不包含数据。它是作为一个select语法查询到的结果集,以此为基表创建的一张虚拟表。对视图的操作对基表有直接影响。
准备视图数据
-- 创建db5数据库CREATE DATABASE db5;-- 使用db5数据库USE db5;-- 创建country表CREATE TABLE country(id INT PRIMARY KEY AUTO_INCREMENT, -- 国家idNAME VARCHAR(30) -- 国家名称);-- 添加数据INSERT INTO country VALUES (NULL,'中国'),(NULL,'美国'),(NULL,'俄罗斯');-- 创建city表CREATE TABLE city(id INT PRIMARY KEY AUTO_INCREMENT, -- 城市idNAME VARCHAR(30), -- 城市名称cid INT, -- 外键列。关联country表的主键列idCONSTRAINT cc_fk1 FOREIGN KEY (cid) REFERENCES country(id) -- 添加外键约束);-- 添加数据INSERT INTO city VALUES (NULL,'北京',1),(NULL,'上海',1),(NULL,'纽约',2),(NULL,'莫斯科',3);
创建视图
- 创建视图语法
CREATE VIEW 视图名称 [(列名列表)] AS 查询语句;
- 创建视图举例
-- 创建city_country视图,保存城市和国家的信息(使用指定列名)CREATE VIEW city_country (city_id,city_name,country_name) ASSELECTc1.id,c1.name,c2.nameFROMcity c1,country c2WHEREc1.cid=c2.id;
查询视图
- 查询视图语法
SELECT * FROM 视图名称;
- 查询视图举例
-- 查询city_country视图SELECT * FROM city_country;
修改视图数据
- 修改视图数据语法
UPDATE 视图名称 SET 列名=值 WHERE 条件;
- 修改视图数据举例
UPDATE city_country SET city_name='深圳' WHERE city_name='北京';
修改视图结构
- 修改视图结构语法
ALTER VIEW 视图名称 (列名列表) AS 查询语句;
- 修改视图结构举例
ALTER VIEW city_country (city_id,city_name,NAME) ASSELECTc1.id,c1.name,c2.nameFROMcity c1,country c2WHEREc1.cid=c2.id;
删除视图
- 删除视图语法
DROP VIEW [IF EXISTS] 视图名称;
- 删除视图举例
DROP VIEW IF EXISTS city_country;
备份与还原
命令操作
数据库备份
mysqldump -u用户名 -p 数据库名称 > 备份文件路径输入密码:
数据库还原
-- 1. 登录数据mysql -u root -p输入密码:-- 2. 创建数据库create databse 数据库名称;-- 3. 使用数据库use 数据库名称;-- 4. 执行文件备份文件source 备份文件路径
图形操作
备份数据库

还原数据库

