数据库学习

数据库

数据库的基本概念

1.数据库(DataBase):简称DB
2.定义:数据库是用于存储和管理数据的仓库。

3.数据库的特点:

  • 1.持久化存储数据。其实数据库就是一个文件系统。
  • 2.方便存储和管理数据。
  • 3.使用了统一的方式操作数据库。— SQL

4.常见的数据库软件:参见《MySQL基础.pdf》
5.MySQL数据库软件

  • 1.安装:参见《MySQL基础.pdf》
  • 2.卸载
				1.datadir="C:/ProgramData/MySQL/MySQL Server 5.5/Data/"
				2.卸载MySQL
				3..删除C:/ProgramData目录下的MySQL文件夹
  • 3.配置
				MySQL服务	
						1.手动。
						2.cmd-->services.msc 打开服务窗口
						3.使用管理员打开cmd
								net start mysql :启动mysql的服务
								net stop mysql:关闭mysql的服务
				MySQL登录
							1.mysql	-uroot	-p密码
							2.mysql	-hip	-uroot	-p连接目标的密码
							3.mysql	--host=ip	--user=root	--password=连接目标的密码
				MySQL退出
							1.exit
							2.quit
				MySQL目录结构
							1.MySQL安装目录
								配置文件	my.ini
							2.MySQL数据目录
								几个概念
										数据库:文件夹
										表:文件
										数据:

SQL

概念:SQL(Structured Query Language)结构化查询语言。

其实就是定义了操作所有关系型数据库的规则,每一种数据库操作的方式存在不一样的地方,称为“方言”。

SQL通用语法

  • 1.SQL语句可以单行或多行书写,以分号结尾。
  • 2.使用空格和缩进来增强语句可读性。
  • 3.MySQL的SQL语句不区分大小写,关键字建议使用大写
  • 4.3种注释
			单行注释:-- 注释内容 或 # 注释内容(mysql 特有)		注意空格是一定要有的。
			多行注释:/* 注释 */

SQL分类

  • DDL(Data Definition Language)数据定义语言
    用来定义数据库对象:数据库、表、列等。关键字:create,drop,alter等
  • DML(Data Mainpulation Language)数据操作语言。
    用来对数据库中表的数据进行增删改。关键字:insert,delete,update等
  • DQL(Data Query Language)数据查询语言。
    用来查询数据库中表的记录(数据)。关键字:select,where等
  • DCL(Data Control Language)数据控制语言(了解)
    用来定义数据库的访问权限和安全级别,及创建用户。关键字:GRANT,REVOKE等

在这里插入图片描述

DDL:操作数据库、表

1.操作数据库:CRUD
1.C(Create):创建
 			Create database 数据库名称;
			Create database if not exists 数据库名称;
			创建数据库,判断是否已经存在,并指定字符集为gbk
			Create database if not exists 数据库名称  character set gbk;
2.R(Retrieve):查询
			查询所有数据库名称:show databases;
			查询某数据库的字符集: show create database 数据库名称;(即查询某个数据库的创建语句)
 3.U(Update):修改
			修改数据库的字符集:alter database 数据库名称 character set 字符集名称;
 4.D(Delete):删除
			删除数据库:drop database 数据库名称;	
			判断数据库存在,存在再删除:drop database if exists 数据库名称;
 5.使用数据库
			查询当前正在使用的数据库名称:select database();
			使用数据库:use 数据库名称; 
2.操作表
		1.C(Create):创建
					 ctreate table 表名(
					 		列名1 数据类型1, 
					 		列名2 数据类型2, 
					 		...
					 		列名n 数据类型n
					 );
					 #注意:最后一列,不需要加逗号(,)
					 常见数据库类型:
					 		1.int :整数类型		age int,
					 		2.double:小数类型	score double(5,2) 指定小数最多有五位,但是保留2位小数
					 		3.date:日期,只包含年月日,yyyy-MM-dd
					 		4.datetime:日期,包含年月日时分秒  	yyyy-MM-dd	HH:mm:ss
					 		5.timestamp:时间戳类型 ,包含年月日时分秒   	yyyy-MM-dd HH:mm:ss
					 				如果将来不给这个字段赋值,或赋值为null,则默认使用当前系统时间,来自动赋值
					 		6.varchar:字符串类型	name varchar(20):姓名最大20个字符(zhangsan 8个字符 张三 2个字符)
创建表:
		create table student(
				id int,
				name varchar(32),
				age int,
				score double(4,1),	
				birthday date,
				insert_time timestamp
		);
	复制表:create table 表名 like 被复制的表名(无法复制表中的内容,是一张空表)
		2.R(Retrieve):查询
					查询某个数据库中所有的表名称:show tables;
					查询表结构:desc 表名;
		3.U(Update):修改
					修改表名:alter table 表名 rename to 新的表名
					修改表的字符集:alter database 表名称 character set 字符集名称;---->alter table s character set utf8
					添加一列:alter table 表名 add 列名 数据类型;
					修改列名称	类型:alter table 表名 change 被修改的列名 新的列名 新的类型 #这个方法既可以该列名又可以改类型,
										将change改成modify只能修改数据类型
					删除列	:alter table 表名 drop 列名  
		4.D(Delete):删除
					删除表:drop table 表名;	
					判断表存在,存在再删除:drop table if exists 表名;
		5.使用数据库
					查询当前正在使用的数据库名称:select database();
					使用数据库:use 数据库名称; 

客户端图形化工具:SQLYog

DML:增删改表中数据

1.添加数据:

语法:insert into 表名(列名1,列名2...列名n) values(值1,值2,...值n);
注意:
		1.列名和值要一一对应。
		2.如果表名后,不定义列名,则默认给所有列添加值
		insert into 表名 values(值1,值2,...值n);
		3.除了数字类型,其他类型需要使用(单双都可以)引号引起来

2.删除数据:

语法:delete from 表名 [where 条件];
注意:
		1.如果不加条件,则删除表中所有记录。
		2.如果要删除所有记录
			a.delete from 表名; 		#不推荐使用,有多少记录就会执行	多少次删除操作
			b.truncate table 表名;  		#推荐使用,效率更高先删除表,然后在创建一张一样的空表

3.修改数据:

语法:
	update 表名 set 列名1 =值1,列名2=值2,....列名n=值n	[where 条件]
注意:
	1.如果不加任何条件,会将表中所有记录全部修改

DQL:查询表中记录

1.语法:

			  select		字段列表
			  from 		表名列表
			  where	条件列表
			  group by	分组字段
			  having	分组之后的条件限定
			  order	by	排序
			  limit		分页限定

2.基础查询

 1.多个字段的查询:select 字段名1,字段名2....from 表名;
 注意:如果查询所有字段,则可以使用*来替代字段的列表。
 2.去除重复::distinct
 3.计算列:一般可以使用四则运算计算一些列的值。(一般只会进行数值型的计算)
 				ifnull(表达式1,表达式2):
 					表达式1:哪个字段需要判断是否为null,
 					表达式2:该字段为null后的替换值。
 4.起别名
 		as:as也可以省略。

例子:

 CREATE TABLE student3 (
 id INT, -- 编号
 NAME VARCHAR(20), -- 姓名
 age INT, -- 年龄
 sex VARCHAR(5), -- 性别
 address VARCHAR(100), -- 地址
 math INT, -- 数学
 english INT -- 英语
);
INSERT INTO student3(id,NAME,age,sex,address,math,english) VALUES (1,'马云',55,'男','
杭州',66,78),(2,'马化腾',45,'女','深圳',98,87),(3,'马景涛',55,'男','香港',56,77),(4,'柳岩
',20,'女','湖南',76,65),(5,'柳青',20,'男','湖南',86,NULL),(6,'刘德华',57,'男','香港',99,99),(7,'马德',22,'女','香港',99,99),(8,'德玛西亚',18,'男','南京',56,65);
TRUNCATE TABLE student3;
SELECT * FROM student3;

-- 去除重复的结果集
SELECT DISTINCT address FROM student3;
SELECT NAME,address FROM student3;

-- 计算math 和english之和
SELECT NAME,math,english,english+math FROM student3;
-- 如果有null参与的计算,计算结果都为null
SELECT NAME,math,english,math+IFNULL(english,0) FROM student3;

-- 起别名
SELECT NAME,math,english,math+IFNULL(english,0) AS 总分 FROM student3;
SELECT NAME,math 数学,english  英语,math+IFNULL(english,0)  总分 FROM student3;

3.条件查询

1.where句子后面跟条件
2.运算符
	*>、<、<=、>=、<>
	*between...and
	*in(集合)
	*LIKE:模糊查询
		占位符:_:单个任意字符 	%:0-多个任意字符
	is null
	and 或 &&	or 或 || 	not 或 !

DQL:查询语句

1.排序查询

语法:order by 子句。	
		order by 排序字段1,排序方式2,	排序字段2 排序方式2....
排序方式:
	ASC:升序,默认的
	DESC:降序 
如果有多个排序条件,则当前边的条件值一样时,才回去判断第二条件 

2.聚合函数:将一列数据作为一个整体,进行纵向的计算。

1.count:计算个数		#1.选择非空的列:主键	#2.count(*)
2.max:计算最大值		min;计算最小值
3.sum:计算和
4.avg:计算平均值
注意:聚合函数的计算,是排除null值
	解决方案:1.选择不包括非空的列进行计算	2.IFNULL函数

3.分组查询

1.语法:group by 分组字段;
2.注意:
	1.分组之后查询的字段:分组字段、聚合函数
	2.where 和having的区别?	
		where在分组之前进行限定,如果不满足条件则不进行分组。having在分组之后进行限定,如果不满足结果,则不会被查询出来
		where后不能跟聚合函数,having可以进行聚合函数的判断   

4.分页查询

1.语法:limit开始的索引,每页查询的条数
2.公式:开始的索引 =(当前的页码-1)*每页显示的条数
3.limit分页是一个MySQL“方言”。

例子:

SELECT * FROM student3 ORDER BY math DESC-- 排序方法;

-- 按照数学成绩排名,如果数学成绩一致,则按英语成绩排名
SELECT * FROM student3 ORDER BY math  ,english  ;

SELECT COUNT(NAME)AS 总人数 FROM student3;

SELECT COUNT(NAME)AS 总人数 FROM student3;

SELECT COUNT(IFNULL(english ,0)) FROM student3;

-- 按照性别分组,分别查询男、女的平均分
SELECT sex,AVG(math),AVG(english),COUNT(id) FROM student3 GROUP BY sex;

-- 按照性别分组,分别查询男、女的平均分要求:分数低于70分的人,不参与分组
SELECT sex,AVG(math),AVG(english),COUNT(id) FROM student3 WHERE math>70 GROUP BY sex;

-- 按照性别分组,分别查询男、女的平均分要求:分数低于70分的人,不参与分组,分组之后,人数要大于2人
SELECT sex,AVG(math),AVG(english),COUNT(id) FROM student3 WHERE math>70 GROUP BY sex HAVING COUNT(id)>2;

-- 按照性别分组,分别查询男、女的平均分要求:分数低于70分的人,不参与分组,分组之后,人数要大于2人
SELECT sex,AVG(math),AVG(english),COUNT(id) 人数 FROM student3 WHERE math>70 GROUP BY sex HAVING 人数>2;

-- 每页显示三条记录
SELECT * FROM student3	LIMIT 0,3; -- 第一页
SELECT * FROM student3	LIMIT 3,3; -- 第2页

-- 公式:开始的索引 =(当前的页码-1)*每页显示的条数

约束

概念:对表中数据进行限定,保证数据的正确性、有效性和完整性。

分类:

1.主键约束:primary key
2.非空约束:not null
3.唯一约束;unique
4.外键约束;foreign key
1.非空约束:not null,值不能为null
1.创建表时添加约束
CREATE TABLE stu(
		id INT,
		NAME VARCHAR(20) NOT NULL -- name为非空
		);

2.删除name 的非空约束
ALTER TABLE stu MODIFY NAME VARCHAR(20);
3.创建表完后,添加非空约束
ALTER TABLE stu MODIFY NAME VARCHAR(20) Not Null;
2.唯一约束:unique,值不能重复。
1. 创建表时,添加唯一约束
CREATE TABLE stu(
		id INT,
		phone_num VARCHAR(20) UNIQUE -- 添加了唯一约束
);
-- 注意msq中唯一约束限定的列的值,可以有多个null
2. 删除唯一约束
-- alter table stu modify phone_num varchar(20);没用
ALTER TABLE stu DROP INDEX phone_num;
3.在创建表之后,添加唯一约束
ALTER TABLE stu MODIFY phone_num  VARCHAR(20) UNIQUE;
3.主键约束:primary key

注意:

1.含义:非空且唯一
2.一张表只能有一个字段为主键
3.主键就是表中记录的唯一标识
1.在创建表时,添加主键约束
CREATE TABLE stu(
	id INT PRIMARY KEY, -- 给id添加主键约束
	NAME VARCHAR(20)
	);
 SELECT * FROM stu;
 
2.删除主键
 -- 错误的方式alter table stu modify id int,	
 ALTER TABLE stu DROP PRIMARY KEY;
 
3.创建完表后,添加主键约束
 ALTER TABLE stu MODIFY id INT PRIMARY KEY;

自动增长一般和主键一起使用
1.概念:如果某一列是数值类型的,使用auto_increment 可以来完成值的自动增长
2.在创建表时,添加主键约束,并完成主键自增长
id int primary key auto_increment
3.删除自动增长。alter table stu modify id int
3.建表后添加自动增长。alter table stu modify id int auto _increment

4.外键约束:foreign key,让表与表产生关系,从而保证数据的正确性
1.在创建表时,可以添加外键
create table 表名(
		...
		外键列
		constraint 外键名称 foreign key 外键列名称 references 主表名称(主表列名称) 
		-- 例子:CONSTRAINT emp_depid_fk FOREIGN KEY (dep_id) REFERENCES department(id);
)
2.删除外键 
ALTER TABLE employee DROP FOREIGN KEY emp_depid_fk;
3.添加外键
ALTER TABLE employee ADD CONSTRAINT emp_depid_fk FOREIGN KEY (dep_id) REFERENCES department(id);
4.级联操作
	添加级联操作:alter table 表名 add constraint 外键名称 foreign key 外键列名称 references 主键名称(主键列名称)
	分类:
		级联更新:on update cascade
		级联删除:on delete cascade
-- 添加外键,并设置级联更新
ALTER TABLE employee ADD CONSTRAINT e FOREIGN KEY 
(dep_id) REFERENCES department(id) ON UPDATE CASCADE; -- cascader

-- 添加外键,并设置级联更新,设置级联删除
ALTER TABLE employee ADD CONSTRAINT e FOREIGN KEY 
(dep_id) REFERENCES department(id) ON UPDATE CASCADE -- cascade
ON DELETE CASCADE ;  

注意:关联外键约束时,必须要现有主表

数据库的设计

1.分类

在这里插入图片描述

案例:分类->旅游路线<|>用户

在这里插入图片描述

 -- 创建旅游线路分类表tab_category 
 -- cid旅游线路分类主键,自动增长 
 -- cname旅游线路分类名称非空,唯一,字符串100 
 CREATE TABLE tab_category (   
		cid INT PRIMARY KEY AUTO_INCREMENT,   
		cname VARCHAR(100) NOT NULL UNIQUE 
		) ;
-- 添加旅游线路分类数据: 
INSERT INTO tab_category (cname) VALUES ('周边游'), ('出境游'), ('国内游'), ('港澳游'); 
-- select * from tab_category; 

-- 创建旅游线路表tab_route 
/* rid旅游线路主键,
自动增长 rname旅游线路名称非空,唯一,
字符串100 price价格 rdate 
上架时间,日期类型 cid 外键,所属分类 */ 
CREATE TABLE tab_route(   
		rid INT PRIMARY KEY AUTO_INCREMENT,   
		rname VARCHAR(100) NOT NULL UNIQUE,   
		price DOUBLE,   
		rdate DATE,   cid INT,   
		FOREIGN KEY (cid) REFERENCES tab_category(cid) 
		) ;
		
-- 添加旅游线路数据 
INSERT INTO tab_route VALUES (NULL, '【厦门+鼓浪屿+南普陀寺+曾厝垵 高铁3天 惠贵团】尝味友鸭面线 住1晚鼓浪屿', 1499, '2018-01-27', 1), 
		(NULL, '【浪漫桂林 阳朔西街高铁3天纯玩 高级团】城徽象鼻山 兴坪漓江 西山公园', 699, '2018-02-22', 3), 
		(NULL, '【爆款¥1699秒杀】泰国 曼谷 芭堤雅 金沙岛 杜拉拉水上市场 双飞六天【含送签费 泰风情 广州 往返 特价团】', 1699, '2018-01-27', 2),
		(NULL, '【经典•狮航 ¥2399秒杀】巴厘岛双飞五天 抵玩【广州往返 特价团】', 2399, '2017-12-23', 2), 
		(NULL, '香港迪士尼乐园自由行2天【永东跨境巴士广东至迪士尼去程交通+迪士尼一日门票+香港如心海景酒店 暨会议中心标准房1晚住宿】', 799, '2018-04-10', 4); 
		
 /*创建用户表tab_user uid用户主键,
 自增长 username用户名长度100,唯一,非空 
 password密码长度30,非空 
 name真实姓名长度100 
 birthday生日 
 sex性别,定长字符串1 
 telephone手机号,字符串11 
 email邮箱,字符串长度100 */ 
 CREATE TABLE tab_user (   
		uid INT PRIMARY KEY AUTO_INCREMENT,   
		username VARCHAR(100) UNIQUE NOT NULL,   
		PASSWORD VARCHAR(30) NOT NULL,   NAME VARCHAR(100),   
		birthday DATE,   
		sex CHAR(1) DEFAULT '男',   
		telephone VARCHAR(11),   
		email VARCHAR(100) 
		) ;
 -- 添加用户数据 
 INSERT INTO tab_user VALUES (NULL, 'cz110', 123456, '老王', '1977-07-07', '男', '13888888888', '66666@qq.com'), 
 (NULL, 'cz119', 654321, '小王', '1999-09-09', '男', '13999999999', '99999@qq.com'); 
 -- select * from tab_user; 
 /*创建收藏表tab_favorite 
 rid  旅游线路
 id,外键 
 date 收藏时间 
 uid用户id,外键 rid和uid不能重复,设置复合主键,同一个用户不能收藏同一个线路两次 */ 
 CREATE TABLE tab_favorite (   
		rid INT,   
		DATE DATETIME,   
		uid INT,   
		-- 创建复合主键    
		PRIMARY KEY(rid,uid),   
		FOREIGN KEY (rid) REFERENCES tab_route(rid),   
		FOREIGN KEY(uid) REFERENCES tab_user(uid) 
		) ;
 
 
-- 增加收藏表数据 
INSERT INTO tab_favorite VALUES
(6, '2018-01-01', 1), -- 老王选择厦门 
(6, '2018-02-11', 2), -- 老王选择桂林 
(7, '2018-03-21', 1), -- 老王选择泰国 
(8, '2018-04-21', 2), -- 小王选择桂林 
(9, '2018-05-08', 1), -- 小王选择泰国 
(10, '2018-06-02', 2); -- 小王选择迪士尼 
  
 SELECT * FROM tab_category;

2.数据库设计的范式

概念:
	设计关系型数据库时,遵从不同的规范要求,设计出合理的关系型数据库。要遵循后面的范式,必须先遵循前边的范式的所有要求。
	这些规范被称作范式。越高的范式数据库的冗余度就越低。 
关系数据库中的关系必须满足一定的要求,即满足不同的范式。
关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴德斯科范式(BCNF)、第四范式(4NF)和第五范式(5NF)。满足最低要求的范式是第一范式(1NF)。在第一范式的基础上进一步满足更多要求的称为第二范式(2NF),其余范式以次类推。一般说来,数据库只需满足第三范式(3NF)就行了。
分类:

1.第一范式:数据库表的每一列都是不可分割的原子数据项,而不能是集合,数组,记录等非原子数据项
2.第二范式:在1NF的基础上,非码属性必须完全依赖于候选码(在1NF的基础上消除非主属性对主码部分的部分函数依赖)

几个概念:
1.函数依赖:A->B,如果通过A属性(属性组)的值,可以确定唯一B属性的值。则称B依赖于A。
例如:学号-->姓名。    (学号,课程名称)-->分数
2.完全函数依赖:A-->B,		如果A是一个属性组,则B属性值的确定,需要依赖于A属性组中所有的属性值。
例如:(学号,课程名称)-->分数
3.部分函数依赖:A-->B	如果A是一个属性组,则B属性的确定只需要依赖A属性组中某一些值即可。
例如:(学号,课程名称)-->姓名
4.传递函数依赖:A-->B,B-->C,	 例如:学号-->系名-->系主任
’如果通过A属性(属性组)的值,可以确定唯一B属性的值,再通过B属性(属性组)的值可以确定唯一C属性的值,则称C传递函数依赖于A。
5.码:如果在一张表中,一个属性或属性组,被其他所有属性所完全依赖,则称这个属性(属性组)为该表的码
例如:该表的码为 (学号,课程名称)
		主属性:码属性组中的所有属性
		非主属性:除码属性组的属性
					

在这里插入图片描述

3.第三范式:属性不能传递依赖于主属性(属性不依赖于其它非主键属性)即消除传递依赖

数据库的备份和还原

1.命令行:

语法:
	备份:mysqldump -u用户名 -p密码 数据库名称  > 保存的路径(d://a.sql)
	还原:
		1.登录数据库
		2.创建数据库
		3.使用数据库
		4.执行文件。source文件路径

2.图形化工具:

多表查询

数据准备:

 # 创建部门表 
CREATE TABLE dept(   
		id INT PRIMARY KEY AUTO_INCREMENT,   
		NAME VARCHAR(20) 
		); 
 
INSERT INTO dept (NAME) VALUES ('开发部'),('市场部'),('财务部');   
# 创建员工表 
CREATE TABLE emp (   
		id INT PRIMARY KEY AUTO_INCREMENT,   
		NAME VARCHAR(10),   gender CHAR(1),   -- 性别   
		salary DOUBLE,   -- 工资   
		join_date DATE,  -- 入职日期   
		ept_id INT,   FOREIGN KEY (dept_id) REFERENCES dept(id) -- 外键,关联部门表(部门表的主键) 
		)   ;
 
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('孙悟空','男 ',7200,'2013-02-24',1); 
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('猪八戒','男 ',3600,'2010-12-02',2); 
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('唐僧','男',9000,'200808-08',2); 
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('白骨精','女 ',5000,'2015-10-07',3); 
INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('蜘蛛精','女 ',4500,'2011-03-14',1); 

笛卡尔积:

有两个集合A,B 去这两个集合的所有组成情况。
要完成多表查询,需要消除无用数据。

多表查询的分类:

  • 1.内连接查询
1.隐式内连接:使用where条件消除无用的数据
				SELECT * FROM emp,dept WHERE emp.`ept_id`=dept.`id`;
				-- 查询员工表的名称,性别,部门表名称
				SELECT emp.`id`,emp.`name`,dept.`name` FROM emp,dept WHERE emp.`ept_id`=dept.`id`;
				 -- 使用别名替换表名
				SELECT t1.`id`,t1.`name`,t2.`name`  FROM emp t1,dept t2 WHERE t1.`ept_id`=t2.`id`;
2.显式内连接: (语法:select 字段列表 from 表名1 [inner] join 表名2 on 条件)
			SELECT * FROM emp INNER JOIN dept ON emp.`ept_id` = dept.`id`;-- inner 可以 省略
			SELECT * FROM emp  JOIN dept ON emp.`ept_id` = dept.`id`;
3.内连接查询:
		·从哪些表中查询
		·条件是什么
		·查询那些字段
  • 2.外连接查
 1.左外连接;(语法: select 字段列表 from 表1 left [outer] join 表2 on 条件;)
 查询的是左表所有数据以及其交集(满足条件)部分
 2.右外连接;(语法: select 字段列表 from 表1 right [outer] join 表2 on 条件;)
 查询的是右表的所有记录和左右表交集的部分
	SELECT * FROM emp INNER JOIN dept ON emp.`ept_id` = dept.`id`;-- inner 可以 省略
	SELECT * FROM emp  JOIN dept ON emp.`ept_id` = dept.`id`;

	SELECT * FROM emp;
	SELECT t1.*,t2.`name` NAME FROM emp t1  LEFT JOIN dept t2 ON t1.`ept_id`=t2.`id`;
	SELECT t1.*,t2.`name` FROM emp t1 RIGHT JOIN dept t2 ON t1.`ept_id`=t2.`id`;

	SELECT * FROM dept t2 RIGHT JOIN emp t1 ON t1.`ept_id`=t2.`id`;
  • 3.子查询
概念:查询中嵌套查询,称嵌套查询为子查询。
例子:
		-- 查询工资最高的员工信息	
		-- 1.查询工资最高是多少 7200
		SELECT MAX(salary) FROM emo;
		-- 查询员工信息,并且工资等于最高 7200
		SELECT * FROM emp WHERE emp.`salary` =7200 ;

		-- 一条语句完成
		SELECT * FROM emp WHERE emp.`salary` = (SELECT MAX(salary) FROM emp);
子查询的不同结果:
1.子查询的结果是单行单列的
		·子查询可以作为条件,使用运算符去判断。
		-- 查询工资小于平均工资的人
		SELECT * FROM emp WHERE emp.`salary` < (SELECT AVG(salary) FROM emp);
2.子查询的结果是多行单列的:
		·子查询可以作为条件,使用运算符in来判断
		 -- 查询财务部和市场部所有员工的信息
		SELECT * FROM emp WHERE emp.`ept_id` IN (SELECT id FROM dept WHERE NAME = '财务部' OR NAME = '市场部' );
.子查询的结果是多行多列的
	·子查询可以作为一张虚拟表参与查询
	-- 查询员工入职日期是2011-11-11日之后的员工信息和部门信息
 	SELECT * FROM emp WHERE emp.`join_date`>'2011-11-11';
 	SELECT * FROM dept t1,( SELECT * FROM emp WHERE emp.`join_date`>'2011-11-11') t2 WHERE t1.`id` = t2.ept_id;

案例

-- 部门表
CREATE TABLE dept (
  id INT PRIMARY KEY PRIMARY KEY, -- 部门id
  dname VARCHAR(50), -- 部门名称
  loc VARCHAR(50) -- 部门所在地
);

-- 添加4个部门
INSERT INTO dept(id,dname,loc) VALUES 
(10,'教研部','北京'),
(20,'学工部','上海'),
(30,'销售部','广州'),
(40,'财务部','深圳');



-- 职务表,职务名称,职务描述
CREATE TABLE job (
  id INT PRIMARY KEY,
  jname VARCHAR(20),
  description VARCHAR(50)
);

-- 添加4个职务
INSERT INTO job (id, jname, description) VALUES
(1, '董事长', '管理整个公司,接单'),
(2, '经理', '管理部门员工'),
(3, '销售员', '向客人推销产品'),
(4, '文员', '使用办公软件');



-- 员工表
CREATE TABLE emp (
  id INT PRIMARY KEY, -- 员工id
  ename VARCHAR(50), -- 员工姓名
  job_id INT, -- 职务id
  mgr INT , -- 上级领导
  joindate DATE, -- 入职日期
  salary DECIMAL(7,2), -- 工资
  bonus DECIMAL(7,2), -- 奖金
  dept_id INT, -- 所在部门编号
  CONSTRAINT emp_jobid_ref_job_id_fk FOREIGN KEY (job_id) REFERENCES job (id),
  CONSTRAINT emp_deptid_ref_dept_id_fk FOREIGN KEY (dept_id) REFERENCES dept (id)
);

-- 添加员工
INSERT INTO emp(id,ename,job_id,mgr,joindate,salary,bonus,dept_id) VALUES 
(1001,'孙悟空',4,1004,'2000-12-17','8000.00',NULL,20),
(1002,'卢俊义',3,1006,'2001-02-20','16000.00','3000.00',30),
(1003,'林冲',3,1006,'2001-02-22','12500.00','5000.00',30),
(1004,'唐僧',2,1009,'2001-04-02','29750.00',NULL,20),
(1005,'李逵',4,1006,'2001-09-28','12500.00','14000.00',30),
(1006,'宋江',2,1009,'2001-05-01','28500.00',NULL,30),
(1007,'刘备',2,1009,'2001-09-01','24500.00',NULL,10),
(1008,'猪八戒',4,1004,'2007-04-19','30000.00',NULL,20),
(1009,'罗贯中',1,NULL,'2001-11-17','50000.00',NULL,10),
(1010,'吴用',3,1006,'2001-09-08','15000.00','0.00',30),
(1011,'沙僧',4,1004,'2007-05-23','11000.00',NULL,20),
(1012,'李逵',4,1006,'2001-12-03','9500.00',NULL,30),
(1013,'小白龙',4,1004,'2001-12-03','30000.00',NULL,20),
(1014,'关羽',4,1007,'2002-01-23','13000.00',NULL,10);



-- 工资等级表
CREATE TABLE salarygrade (
  grade INT PRIMARY KEY,   -- 级别
  losalary INT,  -- 最低工资
  hisalary INT -- 最高工资
);

-- 添加5个工资等级
INSERT INTO salarygrade(grade,losalary,hisalary) VALUES 
(1,7000,12000),
(2,12010,14000),
(3,14010,20000),
(4,20010,30000),
(5,30010,99990);

-- 需求:

-- 1.查询所有员工信息。查询员工编号,员工姓名,工资,职务名称,职务描述
 SELECT t1.`id`,t1.`ename`,t1.`salary`,t2.`jname`,t2.`description` 
 FROM emp t1,job t2
 WHERE t1.`job_id` =t2.`id`;

-- 2.查询员工编号,员工姓名,工资,职务名称,职务描述,部门名称,部门位置
SELECT 
	t1.`id`,t1.`ename`,t1.`salary`,t2.`jname`,t2.`description`,t3.`dname`,t3.`loc`
FROM 
	emp t1,job t2,dept t3
WHERE 
	t1.`job_id`=t2.`id` AND t1.`dept_id` =t3.`id`;
-- 3.查询员工姓名,工资,工资等级
SELECT 
	t1.`ename`,t1.`salary`,t2.*
FROM emp t1,salarygrade t2
WHERE t1.`salary` BETWEEN t2.`losalary` AND t2.`hisalary`;

-- 4.查询员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级
SELECT 
	t1.`ename`,t1.`salary`,t2.`jname`,t2.`description`,t3.`dname`,t3.`loc`,t4.`grade`
FROM 	emp t1, job t2,dept t3 ,salarygrade t4

WHERE 
	t1.`salary` BETWEEN t4.`losalary` AND t4.`hisalary` 
	AND t1.`dept_id`=t3.`id` 
	AND t1.`job_id` =t2.`id`;

-- 5.查询出部门编号、部门名称、部门位置、部门人数
/*
分析: 1.部门编号 部门名称 部门位置 都在 dept中 部门人数 emp中
	2.使用分组查询。按照emp.dept_id完成分组,查询count(id)
	3.使用子查询将第二步的查询结果和dept表进行关联查询
*/
SELECT
	t2.`id`,t2.`dname`,t2.`loc`,t1.`num`
FROM dept t2,(SELECT emp.`dept_id`, COUNT(id) num FROM emp GROUP BY emp.`dept_id`) t1
WHERE t2.`id` = t1.`dept_id`;

 
-- 6.查询所有员工的姓名及其直接上级的姓名,没有领导的员工也需要查询
/*
分析:  1.员工姓名  emp 直接上级的名字: emp
	emp 表的id 和mgr 是自关联的
	2.条件 emp.id = emp.mgr
	3.查询左表的所有数据,和右表的交集数据
		使用左外连接

*/
/*
select 
	t1.`ename`,
	t1.`mgr`,
	t2.`id`,
	t2.`ename`
from emp t1,emp t2
where t1.`mgr` = t2.`id`;

*/
SELECT 
	t1.`ename`,
	t1.`mgr`,
	t2.`id`,
	t2.`ename`
FROM emp t1
LEFT JOIN emp t2
ON t1.`mgr` = t2.`id`;

事务

1.事务的基本介绍

  • 概念:如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败
  • 操作:
1.开启事务:start transaction
2.回滚:rollback 
3.提交:commit
4.MySQL数据库中默认自动提交
	·事务提交的两种方式:
			·自动提交:mysql就是自动提交的,·一条DML(增删改)语句会自动提交一次事务。
			·手动提交:需要先开启事务,再提交   (Oracle 数据库是默认手动提交事务的)
			·修改事务的默认提交方式:
					·查看事务的默认提交方式:select @@autocommit;    -- 1代表自动提交 0代表手动
					·修改默认提交方式:set @@autocommit = 0; 

2.事务的四大特征:

  • 原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败。
  • 持久性:当事务提交或回滚后,数据库会持久化的保存数据。
  • 隔离性:多个事务之间。相互独立。
  • 一致性:事务操作前后,数据总量不变

3.事务的隔离级别

概念:
多个事务之间隔离的,相互独立的。但如果多个数据操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题
存在问题:

  • 脏读:一个事务,读取到另一个事务中没有提交的数据。
  • 不可重复读(虚读):在同一个事务中,两次读取到的数据不一样
  • 幻读:一个事务操作(DML)数据表中所有记录另一个事务添加了一条数据,则第一个事务查询不到自己的修改 。

隔离级别:

  • 1.read uncommitted:读未提交产生问题:脏读、不可重复读、幻读
  • 2.read committed:读已提交的产生的问题,不可重复度、幻读
  • 3.repeatable read:可重复度 幻读 MySQL默认
  • 4.serializable:串行化可以解决所有问题

注意:隔离级别从小到大安全性越来高,但是效率越来越低
数据库查询隔离级别:select @@tx_isolation
数据库设置隔离解绑:set global transaction isolation level 级别字符串

DCL:

  • SQL分类:
    1.DDL:操作数据库和表。
    2.DML:增删改表中数据。
    3.QDL:查询表中数据
    4.DCL:管理用户,授权。
    *DBA:数据库管理员

DCL:管理用户,授权

管理用户
  • 1.添加用户:create user '用户名'@'主机名' identifide by '密码'
  • 2.删除用户:drop user '用户名'@'主机名'
  • 3.修改用户密码:
    UPdate user set password = password ('新密码') where user ='用户名';
    还有一种set password for '用户名'@'主机名'=password(''新密码)
    mysql中忘记了root用户的密码?
    1.cmd - -> net stop mysql (停止mysql服务,需要使用管理员权限运行cmd)
    2.使用无验证方式启动mysql服务:mysql --skip-grant-tables
    3.打开新的cmd窗口,直接输入mysql命令,敲回车。就可以登陆成功
    4.user mysql;
    5.update user set password = password(‘你的新密码’) where user = ‘root’;
    6.关闭 两个窗口
    7.打开任务管理器,手动结束mysql.exe 的进程
    8.启动mysql服务
    9.使用新密码登录
  • 4.查询用户:1.切换到mysql数据库 use mysql; 2.查询user表 select * from user ;
    注意:主机名可以改为%(通配符,表示可以在任意主机使用用户登录数据库)
授权
  • 查询权限:show grants for '用户名'@'主机名';
  • 授予权限:grant 权限列表 on 数据库名.表名 to '用户名'@'主机名'; 所有权限 grant * on *.* to '用户名'@'主机名';
  • 撤销权限:revoke 权限列表 on 数据库名.表名 from '用户名'@'主机名';
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值