Mysql相关笔记(那时候还不太会用markdown,格式可能有点问题)
数据库第一天内容
1.数据库的基本概念
2.Mysql的学习1.安装2.卸载3.配置
3.SQL
数据库的基本概念
1.数据库的英文单词:database 简称DB
2.什么是数据库:*用于存储和管理数据的仓库
3.数据库的特点:1.持久化存储数据的,其实数据库就是一个文件系统2.方便存储和管理数据3.使用统一的方式来操纵数据库SQL
4.常见的数据库软件* 参见《Mysql基础》.pdf
Mysql数据库软件
1.安装
2.卸载
3.配置* Mysql服务的启动1. 手动,右击我的电脑,点击管理2. cmd->service.msc 打开服务的窗口3. 以管理员身份cmd->net stop/start mysql * Mysql登录1. 连接本地mysql:mysql -root -proot2. 连接别人的mysql:mysql -h127.0.0.1 -uroot -pxxxx* Mysql退出 1. exit2. quit * Mysql目录结构1. Mysql安装目录1. bin--二进制的可执行文件,里面有很多的exe命令2. data--数据目录3. include--放了一些c语言的头信息4. lib--jar包5. share--mysql错误信息my.ini--mysql的配置文件2. Mysql数据目录(默认隐藏的文件:ProgramData\\Mysql)1. 几个概念1. 数据库--文件夹,可以有多个数据库2. 表--表就是数据库文件夹里对应的文件(.frm文件)3. 数据--记录,一个表可以存放多个记录
SQL
1. 什么是SQL?Structured Query Language:结构化查询语言其实就是定义了一种操纵所有关系型数据库的语言每一种数据库的操作方式都有不一样的地方,称为“方言”
2. SQL通用语法1. SQL语句可以分成单行或者多行书写,以分号结尾 例如show databases;2. 可使用空格和缩进来增进语句的可读性3. Mysql数据库的sql语句不区分大小写,但是关键字建议使用大写4. 三种注释1. 单行注释 -- 注释内容 --(横线后一定要加空格)或 #注释内容(mysql特有,可以没有空格)2. 多行注释 /* 注释内容 */
3. SQL分类1. DDL(data definition language)数据定义语言:用来定义数据库对象:数据库 表 列等,关键字 create drop alter2. DML(data manipulation language)数据操作语言:(增删改)用来对数据库中表的数据进行增删改查,关键自:insert dalete update3. DQL(data query language)数据查询语言:(查)用来查询数据库中表的记录(数据),关键字:select where等4. DCL(data control language)数据控制语言(了解):用来定义数据库的访问权限和安全级别,以及创建用户。关键字:grant recoke
DDL:操作数据库、表
1.操作数据库:CRUD1.C:CREATE 创建* create database db1 创建数据库* 优化后:create databese if not exists db1; 先判断db1数据库是不是已经存在了,即使存在也不会报错* create database db2 character set gbk; 创建指定字符集的数据库,可以和判断是否存在的语句连在一起 create database if not exists db4 character set gbk;2.R:RETRIEVE查询* show databases; 查询所有数据库的名称* show create databese mysql 查询某个数据库的创建语句 **可以看到该数据库的字符集**3.U:UPDATE 修改* 修改数据库的字符集* alter database db2 character set utf8; 4.D:DELETE 删除* 删除数据* drop database db2; 非常危险的操作,一般不要这么做* drop database if exists db2; 先判断数据库是否存在,然后再删除 5.使用数据库:给进入了数据库才可以对数据库进行操作* 查询当前正在使用的数据库名称* select database();* use db1 ; 进入db1数据库2.操作表1.C:CREATE 创建 1.语法create table 表名(列名1 数据类型1,列名2 数据类型2,...列名n 数据类型n)2.数据类型1. int 整数类型 age int2. double 小数类型 score double(5,2) 5代表该小数一共有5位,小数点后保留2位所以最大值999.993. date 日期,只包含年月日yyyy-MM-dd4. datetime 日期 包含年月日时分秒 yyyy-MM-dd HH:mm:ss5. timestamp 时间戳类型,包含年月日时分秒 yyyy-MM-dd HH:mm:ss如果将来不给这个字段赋值,或赋值为null,则默认使用当前的系统时间,来自动赋值6. varchar 字符串类型:name varchar(20) 表示name字段最大20个字符3.例子create table student(id int,name varchar(32),age int,score double(4,1),birthday date,insert_time timestamp);4,复制表:create table stu like student;2.R:RETRIEVE查询* 查询某个数据库中所有表名称:show tables* 查询表结构:desc 表名;3.U:UPDATE 修改* 修改表名: alter table 表名 rename to 新表名* 修改表的字符集* 查看表的字符集: show create table 表名* 修改表字符集: alter table 表名 character set utf8* 添加一列: alter table 表名 add 列名 数据类型;* 修改列名称和类型:alter table 表名 change 列名 新列名 数据类型只改类型:alter table 表名 modify 列名 新数据类型* 删除列:alter table 表名 drop 列名4.D:DELETE 删除* drop table 表名称;* drop table if exists 表名称;5.使用数据库:
DML 增删改表中的数据
1.添加数据* 语法:* insert into 表名(列名1,列名2,...列名n) values(值1,值2...值n)* 注意1. 列名和值要一一对应2. 如果表名后不定义列名,则默认给所有列添加值3. 除了数字类型,其他类型要用引号引起来,单双引都可以
2.删除数据* 语法:* delete from 表名 [where 条件]* 注意:1. 如果不添加条件,则删除所有记录(太危险,不建议使用,而且,因为有多少条记录,则执行多少次命令,效率太低)2. 一般使用 truncate table 表名: 删除表,然后再创建一个一模一样的空表,推荐使用,效率更高
3.修改数据* 语法* update 表名 set 列名1=值1,列名2=值2,... [where 条件]* 注意1. 如果不加条件,则表中所有记录都会被修改(一般不会这么用)
DQL 查询表中的记录
* select * from 表名
1. 语法:select字段列表from表名列表where条件列表group by分组字段having 分组之后的条件order by排序limit分页限定
2. 基础查询*注意,在我们复制粘贴别人的内容的时候,如果得到了非预料的结果,可以试着检查空字符(是空字符不是空格)1. 查询多个字段 select name,age from stu2;2. 去除重复(distinct) select distinct address from stu2;3. 计算列 select name,math,english,math+english from stu2;但是计算的结果中,柳青数学86,但是用于英语没考是null,所以相加后值为null如果有null参与的计算,计算结果都为nullselect name,math,english,math+ifnull(english,0) from stu2但是计算完后,那个第四列计算结果所在的列列名为math+ifnull(english,0),实在是太难看了,所以我们可以起别名ifnull(表达式1,表达式2) 表达式1:那个字段需要判断是否为null表达式2:如果该字段为null时的替换值4. 起别名(as) select name,math,english,math+ifnull(english,0) as 总分 from stu2
3. 条件查询1. where字句后跟条件2. 运算符1. > < <= >= = <>null不可以使用=判断,应该使用is nullSELECT * FROM stu2 WHERE english IS NULL;2. between and : 在什么之间3. in(集合) : 集合表示多个值,使用逗号分割,表示在什么范围之内4. like '张%' : 模糊查询* 占位符* _:表示单个任意字符* %:表示任意多个字符5. is null: 查询某一列为null的值 注意:不能写=null6. and/&& or/|| not/! 与或非-- 查询年龄大于20的SELECT * FROM stu2 WHERE age>=20;SELECT * FROM stu2 WHERE age=20;-- 查询年龄在20到30之间的人SELECT * FROM stu2 WHERE age>=20 AND age<=30;SELECT * FROM stu2 WHERE age BETWEEN 20 AND 30;-- 查询22岁的人,18岁,25岁SELECT * FROM stu2 WHERE age=22 OR age=18 OR age=25;SELECT * FROM stu2 WHERE age IN(22,18,25);-- 查询英语缺考的人SELECT * FROM stu2 WHERE english=NULL;-- null不可以使用=判断,是一个特殊的值SELECT * FROM stu2 WHERE english IS NULL;SELECT * FROM stu2 WHERE english IS NOT NULL;-- 模糊查询,查询班级里面姓马的同学SELECT * FROM stu2 WHERE NAME LIKE '马%';-- 查询姓名的第二个字是化的人SELECT * FROM stu2 WHERE NAME LIKE '_化%';-- 查询姓名是三个字的人SELECT * FROM stu2 WHERE NAME LIKE '___';-- 查询姓名中包含马的人SELECT * FROM stu2 WHERE NAME LIKE '%德%';
数据库第二天内容
1. DQL查询语句1. 排序查询2. 聚合查询3. 分组查询4. 分页查询
2. 约束
3. 多表之间的关系
4. ==三大范式==
5. 数据库的备份和还原
DQL查询语句
排序查询
语法:
- order by 排序字段1 排序方式1,排序字段2 排序方式2…
- select * from stu2 order by math
- select * from stu2 order by math asc , english asc – 按照数学成绩排名,如果数学成绩一样,则按照英语成绩排名
- order by 排序字段1 排序方式1,排序字段2 排序方式2…
排序方式:
- asc 升序排序 默认
- dsc 降序排序
注意
- 如果有多个排序调价,则当前面的排序结果一样的时候,才会判断第二条件
聚合查询:将一列数据作为一个整体,进行纵向的计算。(比如求数学的平均分)
- count:计算个数
- select count(name) from stu2;
- select count(ifnull(english , 0)) from stu2;
- 一般选择非空的列:主键
- count(*) 只要这一行有一个数据不为null,则加1 select count( * ) from stu2;
- max:计算最大值
- select max(english) from stu2;
- min:计算最小值
- select min(english) from stu2;
- sum:计算和
- select sum(math) from stu2;
- avg:计算平均值
- 注意:聚合函数的计算,会排除null值
- 解决方案:
- 选择不包含非空的列进行计算
- ifnull函数
- 解决方案:
- count:计算个数
分组查询
语法:group by 分组字段
注意:
分组之后,查询的字段:分组字段,聚合字段(比如我们按性别分类,这分组字段就是sex)
按性别分组,分别查询男女同学数学的平均成绩
SELECT sex,AVG(math) FROM stu2 GROUP BY sex;
按照性别分组,分别查询男女同学的平均分,但是分数低于70分的不参与分组
SELECT sex,AVG(math) FROM stu2 WHERE math>70 GROUP BY sex
按照性别分组,分别查询男女同学的平均分,但是分数低于70分的不参与分组,分组之后人数需要大于两个人
SELECT sex,AVG(math),COUNT(id) FROM stu2 WHERE math>70 GROUP BY sex HAVING COUNT(id) > 2;
where和having的区别?
- where在分组之前限定,如果不满足条件,则不参与分组。having在分组之后进行限定,如果不满足条件,则不会被查询出来
- where之后不可以跟聚合函数,having可以进行聚合函数的判断
分页查询
语法:limit 开始的索引,每页查询的条数;
– 每页显示三条记录
SELECT * FROM stu2 LIMIT 0,3; – 第一页
SELECT * FROM stu2 LIMIT 3,3; – 第二页
–公式:开始的索引=(当前的页面-1)*每页显示的条数SELECT * FROM stu2 LIMIT 6,3; – 最后一页有多少显示多少
分页操作是一个方言(即不同数据库分页的方式不一样,这里的分页方式是mysql的方言)
约束
- 概念:对表中的数据进行限定,保证数据的准确性,有效性和完整性。(例如我们不设置某行的名字,很明显这行数据是无用的,是不应该添加到数据库里面)
- 分类:
- 主键约束:primary key
- 非空约束:not null
- 唯一约束:unique
- 外键约束:foreign key
非空约束not null
在创建表时,添加约束
创建表后,添加约束
– 创建表的时候添加非空约束
CREATE TABLE stu3(
id INT,
NAME VARCHAR(20) NOT NULL – name 为非空约束
);
DESC stu3;ALTER TABLE stu3 MODIFY NAME VARCHAR(20); – 创建表后,删除非空约束
– 创建表完成后,添加非空约束
ALTER TABLE stu3 MODIFY NAME VARCHAR(20) NOT NULL;
唯一约束unique
注意:即使添加了唯一约束后,仍然可以有多个值为null
– 创建表的时候,添加唯一约束
CREATE TABLE stu3(
id INT,
phone_number VARCHAR(20) UNIQUE -- 添加了唯一约束
);
SELECT * FROM stu3;
– 删除唯一约束
ALTER TABLE stu3 MODIFY phone_number VARCHAR(20);
– 虽然不报错,但是这个方法无法删除唯一约束ALTER TABLE stu3 DROP INDEX phone_number;
– 在创建表后,添加唯一约束
ALTER TABLE stu MODIFY phone_number VARCHAR(20) UNIQUE;
– 但是注意,若添加的时候表内已经有了数据,切该列有重复值,则添加唯一约束会报错
唯一约束primary key
注意:
- 含义:非空且唯一
- 一张表,只可以有一个字段为主键
- 主键就是表中记录的唯一标识
在创建表的时候,添加主键约束
create table stu3(
id int primary key,
name varchar(20)
);
CREATE TABLE stu3(
id INT PRIMARY KEY,
NAME VARCHAR(21)
);
SELECT * FROM stu3;
– 删除主键
ALTER TABLE stu3 MODIFY id INT;
– 虽然执行成功,但是并不会生效,这是错误写法
ALTER TABLE stu3 DROP PRIMARY KEY;
– 不用指定是哪一列,因为一个表只有一个主键,但是非空属性还保存着– 创建表后添加主键
ALTER TABLE stu MODIFY id INT PRIMARY KEY;
自动增长
概念:如果某一列是数值类型的,使用auto_increment 来完成值的自动增长,一般配合主键一起使用
-- 在创建表时,添加主键约束,并且完成主键的自增长
CREATE TABLE stu3(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(22)
);
SELECT * FROM stu3;
INSERT INTO stu3 VALUES(NULL,'ddd');-- 可以自动增长,也可以手动设置值,他自动增长的时候只和上一行数据有关
-- 删除字段增长
ALTER TABLE stu3 MODIFY id INT; -- 因为主键删除不了,所以这么写也可以
-- 添加自动增长
ALTER TABLE stu3 MODIFY id INT AUTO_INCREMENT;
外键约束 foreign key:让表和表之间产生关系,从而保证数据的正确性。
在创建表的时候,可以添加外键
语法:
create table 表名(
...
外键列
constraint 外键名称 foreign key 外键列名称 references 主表名称(主表列名称)
)
CREATE TABLE tab_route(
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)
);
删除外键
ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;
添加外键
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主表列名称--一般是主键);
级联操作—在添加外键的时候,设置级联,可以很方便的修改外键所管理的主表列的值,主表列的值修改会带动对应外键的值一起去修改
- 级联更新:
ALTER TABLE employee ADD CONSTRAINT emp_dept_fk FOREIGN KEY (dep_id) REFERENCES department(id) ON UPDATE CASCADE;
- 级联删除:但是也有弊端,使用的时候要谨慎
ALTER TABLE employee ADD CONSTRAINT emp_dept_fk FOREIGN KEY (dep_id) REFERENCES department(id) ON delete CASCADE;
- 两个可以写一起
ALTER TABLE employee ADD CONSTRAINT emp_dept_fk FOREIGN KEY (dep_id) REFERENCES department(id) ON delete CASCADE on update cascade;
- 级联更新:
多表之间的关系
多表之间的关系
分类:
- 一对一
- 如:人和身份证,一个人只有一个身份证,一个身份证也只可以对于一个人
- 一对多|多对一
- 如:部门和员工,一个部门有多个员工,一个员工只可以对于一个部门
- 多对多
- 如:学生和课程,一个学生可以选择多门课程,一个课程也可以被多个学生选择
- 一对一
实现关系:
- 一对多关系实现(如部门和员工):在多的一方建立外键,指向一的一方的主键
- 多对多关系实现(学生和课程):需要借助第三个表:中间表,中间表至少包含两个字段(这两个字段一般为联合主键),这两个字段作为第三张表的外键,分别指向两张表的主键
- 一对一关系实现(学生和学生证):在任意的一方添加外键来指向另一方的主键,与此同时,该外键需要设置唯一约束
案例:旅游网站
- 三张表:
- 旅游线路分类
- cid name
- 旅游线路
- rid name price
- 用户
- id username password
- 旅游线路分类
- 表的设计
- 一个分类表对应多个线路表,所以分类表和线路表是一对多的关系,所以一个在线路表内添加一个外键,指向分类表的主键cid
- 一个用户可以收藏多个线路,一个线路可以被多个用户收藏,所以用户表和线路表是多对多的关系,所以应该创建一个中间表(rid,uid),中间表的两个外键分别指向线路表和用户表的主键
-- 创建旅游线路分类表 tab_category
-- cid 旅游线路分类主键,自动增长
-- cname 旅游线路分类名称非空,唯一,字符串 100
CREATE TABLE tab_category (
cid INT PRIMARY KEY AUTO_INCREMENT,
cname VARCHAR(100) NOT NULL UNIQUE
);
-- 创建旅游线路表 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) ); /*创建用户表 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) ); /*
创建收藏表 tab_favorite
rid 旅游线路 id,外键
date 收藏时间
uid 用户 id,外键
rid 和 uid 不能重复,设置复合主键,同一个用户不能收藏同一个线路两次
*/
CREATE TABLE tab_favorite (
rid INT, -- 线路id
DATE DATETIME,
uid INT, -- 用户id
-- 创建复合主键
PRIMARY KEY(rid,uid),
FOREIGN KEY (rid) REFERENCES tab_route(rid),
FOREIGN KEY(uid) REFERENCES tab_user(uid)
);
- 三张表:
三大范式
概念:设计数据库的时候,需要遵循的一些规范。
- 设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求成为不同的范式,各种范式呈递次规范,越高的范式,数据库冗余越小
- 目前关系数据库有六种范式:学生表(学号,姓名,系名,系主任,课程名称,分数)
- 第一范式(1NF)
- 每一列都是不可分割的原子数据项
- 缺陷:
- 存在非常严重的数据冗余
- 数据添加存在问题
- 删除数据也存在问题
- 第二范式(2NF)
- 在1NF的基础上,非码属性必须完全依赖于候选码(在1NF的基础上消除非主属性对主码的部分函数依赖,即非主属性要完全依赖于主属性)
- 函数依赖:如果通过A的属性(属性组)的值,可以唯一确定B属性的值,则称B依赖于A A->B
- 如:学号—>姓名 (学号,课程名称)—>分数
- 完全函数依赖:如果A是一个属性组,则B属性值的确定需要依赖于A属性组中的全部属性
- 如:(学号,课程名称)—>分数
- 部分函数依赖:如果A是一个属性组,则B属性值的确定只需要依赖于A属性组中的部分属性
- 如:(学号,课程名称)—>系名,例如学生表中,候选码为学号和课程名称,但是存在部分函数依赖,例如系名,系主任,姓名依赖于学号而不依赖于(学号,课程名称)
- 传递函数依赖:A—>B B—>C,如果通过A属性的值可以唯一确定B属性的值,再通过B属性的值可以唯一确定C属性的值,则称C传递函数依赖于A
- 如:学号—>系名 系名—>系主任
- 总结,所以我们应该进行表的拆分,将学生表拆分为选课表(学号,课程名称,分数)和学生表(学号,姓名,系名,系主任),此时,函数中不存在非主属性对主属性的部分函数依赖了
- 缺陷:
- 数据添加存在问题
- 数据删除存在问题
- 第三范式(3NF)
- 在2NF的基础上,任何非主属性不依赖于其他非主属性(在2NF的基础上消除传递依赖)
- 我们发现了问题,就是进行拆分后的学生表,存在传递依赖,学号–>系名 系名–>系主任,所以我们应该添加一个系表(系名,系主任)
- 巴斯—科德范式(BCNF)
- 在3NF的基础上,任何非主属性依赖不能对主键子集依赖(在3NF基础上消除对主码子集的依赖)
- 第四范式(4NF)
- 第五范式(5NF 又称完美范式)
- 第一范式(1NF)
了解一些课本知识
首先说明,键字=码字,所以主关键字=主码=主键,候选键=候选码=候选关键字
各种码:
候选码/超级玛:可以唯一的表示一个元组的属性或者属性集,一个表可以有多个候选码,例如学生表(学号,姓名,身份证),那么学号可以作为候选码,身份证也可以作为候选码
- 候选码是没有多余属性的,例如(学号,身份证)不可以作为候选码,因为只需要一个就可以唯一的标识一个元组
- 最小性:任一候选键的任何真子集都不可以唯一的标识一个记录
- 非空性
- 标识性
主码:从候选码中人为的挑选一个作为主码,例如上面的学生表中,我们可以选择学号作为主码,也可以选择身份证号作为主码
- 唯一性
- 标识性:一个表的所有记录都具有不同的主码取值
- 非空性
主属性:包含在任意候选码中的属性为主属性,例如学号和身份证就是主属性
非主属性:姓名就是非主属性
全码:当所有的属性共同构成候选码的时候,称该码为全码
码/超键/键:可以唯一标识一条记录的属性或者属性集,即含有候选码就行,例如(学号,姓名)是一个码,(姓名,身份证)是一个码。
表
- 一个表就是一个关系
- 表中一行为一个元组
- 一列为一个属性,要和属性名区别开
- 元组中的一个属性值为分量(关系必须规范化:分量不可再分)
- 关系名就是表名
- 关系模式就是表头
数据库的备份和还原
- 命令行方式
- 备份语法:mysqldump -u用户名 -p密码 要备份的数据库名称 > 要保存的路径
- 还原语法:
- 登陆数据库
- 创建数据库
- 使用数据库
- 执行文件 source 文件路径
- 图形化工具的方式
数据库第三天内容
1. 多表查询
2. 事务
3. DCL(一般由DBA完成)
多表查询
提前准备的表
创建部门表
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, -- 入职日期
dept_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,'2008-08-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,取这两个集合的所有组成情况,要完成多表查询,需要消除无用的数据
多表查询的分类
内连接查询
- 隐式内连接:使用where条件来消除无用的数据
- 例子:
- – 查询员工表的名称,性别。部门表的名称
SELECT emp.name,gender,dept.name FROM emp,dept WHERE emp.dept_id=dept.id;
– 简化形式(起别名)
SELECT
t1.name,t1.gender,t2.name
FROM
emp t1,dept t2
WHERE
t1.dept_id=t2.id;
- – 查询员工表的名称,性别。部门表的名称
- 例子:
- 显式内连接
- 语法:select 字段列表 from 表名1 inner join 表名2 on 条件; – inner可以省略
SELECT * FROM emp INNER JOIN dept ON emp.dept_id=dept.id;
- 内连接查询需要知道的地方
- 从哪些表查数据
- 查询条件是什么
- 查询哪些字段
- 隐式内连接:使用where条件来消除无用的数据
外连接查询
左外连接
- 语法:select 字段列表 from 表1 left outer join 表2 on 条件
- 查询的是左表所有数据以及其交集部分
右外连接
语法:select 字段列表 from 表1 right outer join 表2 on 条件
查询的是右表所有数据以及其交集部分
代码
- – 查询所有员工信息,如果员工有部门,则查询部门的名称,没有部门,则不显示部门名称
``SELECTt1.*,t2.nameFROMemp t1,dept t2WHERE`
t1.dept_id=t2.id; - – 只有五条信息,因为小白龙的还没有入职,没有部门id,所以无法查询到,很显然,查询是失败的
– 所以我们可以使用左外连接
``SELECTt1.*,t2.nameFROMemp t1LEFT OUTER JOINdept t2ONt1.dept_id=t2.id
;`
- – 查询所有员工信息,如果员工有部门,则查询部门的名称,没有部门,则不显示部门名称
子查询:
概念:查询中嵌套查询,称嵌套查询为子查询
– 查询工资最高的员工信息
– 普通方法,分为两步走,先找出工资最高为多少,然后再查询出工资为最高值的员工信息
SELECT MAX(salary) FROM emp;
SELECT * FROM emp WHERE salary=9000;
– 想用一条sql就完成操作,我们可以使用内连接
SELECT * FROM emp WHERE salary=(SELECT MAX(salary) FROM emp);
子查询的不同情况
- 子查询的结果是单行单列的
- 子查询可以作为条件,使用运算符去判断
- – 查询员工工资小于平均工资的人
SELECT * FROM emp WHERE emp.salary
< (SELECT AVG(salary) FROM emp);
- – 查询员工工资小于平均工资的人
- 子查询可以作为条件,使用运算符去判断
- 子查询的结果是多行单列的
- 子查询可以作为条件,使用运算符in来判断
- – 查询财务部和市场部所有的员工信息
SELECT * FROM emp WHERE dept_id IN (SELECT id FROM dept WHERE NAME='财务部' OR NAME='市场部');
- – 查询财务部和市场部所有的员工信息
- 子查询可以作为条件,使用运算符in来判断
- 子查询的结果是多行多列的
- 子查询可以作为一张虚拟表
-- 查询员工的入职日期是2011年11月11日之后的员工信息和部门信息` `SELECT * FROM dept t1,(SELECT * FROM emp WHERE emp.join_date>'2011-11-11') t2 WHERE t1.id=t2.dept_id;
- 子查询可以作为一张虚拟表
- 子查询的结果是单行单列的
练习
-- 需求:-- 1.查询所有员工信息。查询员工编号,员工姓名,工资,职务名称,职务描述 SELECTt1.`id`,t1.`ename`,t1.`salary`,t2.`jname`,t2.`description` FROMemp t1,job t2 WHEREt1.`job_id`=t2.`id`; -- 2.查询员工编号,员工姓名,工资,职务名称,职务描述,部门名称,部门位置 SELECTt1.`id`,t1.`ename`,t1.`salary`,t3.`jname`,t3.`description`,t2.`dname`,t2.`loc` FROMemp t1,dept t2,job t3 WHEREt1.`dept_id`=t2.`id` AND t1.`job_id`=t3.`id`; -- 3.查询员工姓名,工资,工资等级 SELECTt1.`ename`,t1.`salary`,t2.`grade` FROMemp t1,salarygrade t2 WHEREt1.`salary` BETWEEN t2.`losalary` AND t2.`hisalary`; -- 4.查询员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级 SELECTt1.`ename`,t1.`salary`,t2.`jname`,t2.`description`,t3.`dname`,t3.`loc`,t4.`grade` FROMemp t1,job t2,dept t3,salarygrade t4 WHEREt1.`job_id`=t2.`id` AND t1.`dept_id`=t3.`id` AND t1.`salary` BETWEEN t4.`losalary` AND t4.`hisalary`; -- 5.查询出部门编号、部门名称、部门位置、部门人数 SELECTt1.`id`,t1.`dname`,t1.`loc`,COUNT(t2.`ename`) AS 部门人数 FROMdept t1 LEFT OUTER JOIN emp t2 ONt2.`dept_id`=t1.`id` GROUP BYt1.`dname`; -- 6.查询所有员工的姓名及其直接上级的姓名,没有领导的员工也需要查询 SELECTt1.`ename`,t2.`ename` FROMemp t1 LEFT OUTER JOIN emp t2 ONt1.`mgr`=t2.`id`;
事务
事务的基本介绍
概念:如果一个包含多个步骤的业务操作被事务管理,那么这些操作要么同时成功,要么同时失败
例如:张三给李四转账500,含有三个步骤,如果这三个步骤没有被事务管理,如果第二部出现异常,代码就会跳转,而不会执行下面的步骤,那么就会出现张三的账户-500而李四的账户没有+500,如果被事务管理了,这三个操作就会变成一个整体,某一步出现异常就会回滚
1. 查询张三余额是否大于500 2. 张三账户-500 3. 李四账户+500
操作
- 开启事务 start transaction
- 回滚 rollback
- 提交 commit
mysql数据库中,事务默认自动提交
- 一条DML(增删改)语句会自动提交一次事务
- 事务提交的两种方式
- 自动提交
- mysql就是自动提交的,一条DML(增删改)语句会自动提交一次事务
- 手动提交
- 需要先开启事务,再提交
- oralce数据库是默认手动提交事务
- 自动提交
- 修改事务的默认提交方式
- 查看事务的默认提交方式: select @@autocommit; 返回1,代表自动提交,0代表手动提交
- 修改默认提交方式:set @@autocommit=0;之后你写DML语句时,如果不写commit是不会生效的(会产生临时数据,但是如果此时你关掉mysql然后重启,会发现数据没有变化)
事务的四大特征(面试常问)
- 原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败
- 持久性:事务一旦回滚或者提交,数据库会持久化的保存数据
- 隔离性:多个事务之间,相互独立。
- 一致性:事务操作前后,数据总量不变
事务的隔离级别(了解)
概念:多个事务之间,相互独立的,但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别可以避免这些问题
存在的问题:
- 脏读:一个事务,读取到另一个事务中没有提交的数据
- 不可重复读:同一个事务中,两次读取到的同一个数据不一样
- 幻读:一个事务,去操作DML数据表中所有的数据,另一个事务添加了一条数据,则第一个事务查询不到自己的修改。
隔离级别(4种)
- read uncommitted:读未提交
- 产生的问题:脏读,不可重复读,幻读。
- read committed(oracle默认):读以提交
- 产生的问题:不可重复读,幻读
- repeatable read(mysql默认):可重复读
- 产生的问题:幻读
- serializable:串行化
- 解决所有的问题
- 注意:隔离级别从小到大,安全性越来越高,但是效率越来越低
- 数据库查询隔离级别:select @@tx_isolation;
- 数据库设置隔离级别:set global transaction isolation level 级别字符串;不会立即生效,需要重启后才可以生效
- read uncommitted:读未提交
DCL(了解)
sql分类:
- DDL:操作数据库和表
- DML:增删改表中数据
- DQL:查询表中数据
- DCL:管理用户,授权
DBA:数据库管理员:管理数据库的
DCL:管理用户,授权
管理用户
添加用户 create user 用户名@主机名 identified by 密码
删除用户 drop user 用户名@主机名
修改用户密码 update user set password=password(‘新密码’) where user=‘用户名’
set password for ‘用户名’@‘主机名’=password(‘新密码’);
- 在mysql中,如果忘记了root用户的密码
- cmd—> net stop mysql 停止mysql服务(需要管理员运行)
- 使用无验证方式启用mysql服务 : mysqld --skip-grant-tables
- 这里会发现,光标不动了,不要关闭该cmd窗口,打开一个新的cmd窗口,输入mysql,就可以无验证的进入mysql,然后修改root用户的密码就可以了
- 打开任务管理器,手动的结束mysqld服务
- 管理员打开mysql服务 net start mysql
- 在mysql中,如果忘记了root用户的密码
查询用户 :mysql(mysql自带的四个数据库中的mysql数据库)数据库中的user表
权限管理
- 查询权限 show grant for ‘用户名’@‘主机名’ 会返回一条语句
- 授予权限 grant 权限列表 on 数据库名.表名 to ‘用户名’@‘主机名’ ;
- 授予所有表的所有权限 grant all on *.* to ‘zhangsan’@‘localhost’
- 撤销权限 revoke 权限列表 on 数据库名.表名 from ‘用户名’@‘主机名’ ;
Mysql相关笔记(那时候还不太会用markdown,格式可能有点问题)相关推荐
- linux 下安装mysql相关笔记
安装mysql yum -y install mysql-server yum -y install mysql mysql-devel 都显示完成就可以了 查看mysql的版本号 rpm -qi m ...
- 腾讯云TVP大佬十年心血MySQL工作笔记,看完还不懂MySQL来打我!
TVP简介(腾讯云最具价值专家) TVP(Tencent Cloud Valuable Professional),腾讯云最具价值专家,是腾讯云授予云计算领域技术专家的一个奖项.而今天小编分享的这份资 ...
- MySQL学习笔记-基础篇1
MySQL 学习笔记–基础篇1 目录 MySQL 学习笔记--基础篇1 1. 数据库概述与MySQL安装 1.1 数据库概述 1.1.1 为什么要使用数据库 1.2 数据库与数据库管理系统 1.2.1 ...
- MySQL学习笔记(1)——高可用组复制
MySQL学习笔记(1)--高可用组复制 积土成山,风雨兴焉.积水成渊,蛟龙生焉. 一.概念 组复制(MySQL Group Replication,MGR)是MySQL官方在MySQL 5.7.17 ...
- 涨薪神作,阿里内部火爆的实战文档和搭建项目笔记,你还怕没有项目可做吗
前言 认识一个事物最好的方式就是首先去了解它的历史. 随着Spring功能的不断丰富,版本的不断迭代发展,Spring 框架渐渐暴露出了一些问题和弊端.例如太多样板化的配置.繁琐复杂的使用过程等,我们 ...
- JavaEE 企业级分布式高级架构师(六)MySQL学习笔记(6)
MySQL学习笔记 性能优化篇 性能优化的思路 慢查询日志 慢查询日志介绍 开启慢查询功能 演示一 演示二 分析慢查询日志 MySQL自带的mysqldumpslow 使用percona-toolki ...
- (B站动力节点老杜MySQL教程)MySQL课堂笔记-day01.txt
文章目录 文件来源/资料下载: MySQL课堂笔记-day01.txt 1.sql.DB.DBMS分别是什么,他们之间的关系? 2.什么是表? 3.学习MySQL主要还是学习通用的SQL语句,那么SQ ...
- (B站动力节点老杜MySQL教程)MySQL课堂笔记-day02.txt
文章目录 文件来源/资料下载: MySQL课堂笔记-day02.txt 1.关于查询结果集的去重? 2.连接查询 2.1.什么是连接查询? 2.2.连接查询的分类? 2.3.在表的连接查询方面有一种现 ...
- MySQL学习笔记(三)查询
写在前面:本篇为作者自学总结,学习内容为课堂所学和网络学习笔记汇总,对于内容引用部分在文中和文末注明. 文章仅供参考,如需深入了解,请查阅MySQL参考手册.附上下载链接: 链接:https://pa ...
最新文章
- 计算机视觉 | 优秀实用的OpenCV开源项目汇总
- 自定义SOAP消息头
- Flex开发实战(一)--Flex的详细介绍
- ingress controller 和ingress使用实例
- 清华北大毕业生都进体制内了?
- 关于Git下载上传项目的操作指令
- 【转】Magento2 安装系列一 虚拟机、CentOS7 安装
- kij是不是c语言语句,C语言考试题库及答案分析(总35页).doc
- (原创)boost.property_tree解析xml的帮助类以及中文解析问题的解决
- 语音情感识别的优选方法与流程
- HCIE-Security Day7:6个实验理解目的NAT
- Atitit 数据存储的数据表连接attilax总结
- 利用Python下载文件
- 【游戏开发】游戏开发书籍汇总
- FLV格式解析及其解析器的实现
- 冒险者传说pc6java_我的世界之冒险者传说整合包游戏
- 大一大学计算机应用基础课后简答题,2017大一计算机应用基础试题及答案
- Appium环境搭建教程
- MSP430F149的TIMERA定时中断理解
- 中枢神经系统解剖结构图,神经系统的解剖结构