旧时笔记-MySQL
前言
该文章是站主前期学习笔记,搬运于此方便查询。
暂没有作格式处理。
正文
数据库概述
- MySQL就是数据库管理系统,专门用于管理数据的。
- 目的是简化对文件的操作,通过简单的SQL语句即可做到对文件的增删改查。
- 常见的数据库管理系统:
Oracle、MySQl、DB2、Sybase、MS SqlServer(支持标准SQL的数据库管理系统)
- 其中,Oracle是昂贵的,数据安全级别较高的,传统企业常用的
- MySQL的便捷免费开源,让其成为互联网产业最常用的数据库管理系统。
- MySQL数据库的端口:3306
- 表:参考Excel
SQL:
结构化查询语言,是一门标准通用的高级语言,适用于所有数据库产品。
DBMS:
Database Management System,数据库管理系统
DB:
DataBase,数据库,实际在硬盘上以文件的形式存在。
MySQL部分命令
- 登录
mysql -u用户名 -p密码
- 列出数据库:
show databases;
- 创建数据库(传入的名字都会转换为小写)
create database 名字;
- 使用数据库
ues 数据库名字;
- 列出当前数据库中的表
show tables;
- 初始化数据:(初始化数据前要先选择使用数据库)
source sql;
- 删除数据库
drop database 数据库名字;
- 查看表结构
desc 表名字;
9、\c 终止语句
10、show creat table emp;
查看建表语句
11、distinct,去重
12、union,链接
这个关键字常用于拼接两张不关联的表。有关联数据的拼接可以使用其他关键字。
SQL语句分类
DQL :
Data Query Language 数据查询语句,用来在数据库中查询的语言,select就在这里;
DML:
Data Manipulation Language 数据操作语言,一般用来做表中数据的增加和删除;
insert、delete、updata
DDL:
Data Difinition Language 数据定义语言,用于对表的结构进行增删改;
create、drop、alter
TCL:
事务控制语言
DCL:
Data Control Language 数据控制语言,一般是DBA才会用zd到的数据库用户管理及日常维护语言。grant授权、revoke撤销权限
SQL语句中的执行顺序
select 5、列出/找出
….
from 1、在…表中
…
where 2、条件
…
group by 3、分组
…
having 4、过滤
…
order by 6、排序
…
limit 7、取几个
…
表查询
简单的DQL
- 查询:
select 字段名1,字段名2………….from 表名;
- 查出的月薪乘12
select empno, ename, sal*12 from emp;
- 查询出来的字段显示为中文或其他字符
select empno as ‘员工编号’, ename as ‘员工姓名’, sal*12 as ‘年薪’ from emp;
- 条件查询:
select 要检索的字段名………..from 表明 where 条件;
- 模糊查询:
ename like ‘A%’
所有名字开头是A的员工
ename like ‘_A%’
所有名字第二个字母是A的员工
ename like ‘%\_%’
所有名字包含下划线的员工
- 包含in
select * from emp where job in (‘manager’,’salesman’);
职业为’manager’,’salesman’繁荣员工;
- 排序:
排序使用order by语句,后面跟上排序字段
select * from emp order by sal;
按照薪水升序排序
select * from emp order by sal,job;
按照薪水升序排序,薪水相同时再按照工作类型排序
若要手动指定排序顺序,在字段名后加asc代表升序,加desc代表降序。
- 转换为其他字段名:
as 其他想要编程的名字。
SQL中的运算符
运算符 | 说明 |
= | 等于 |
<>或!= | 不等于 |
< | 小于 |
<= | 小于等于 |
> | 大于 |
>= | 大于等于 |
between … and …. | 两个值之间,等同于 >= and <= |
is null | 为null(is not null 不为空) |
and | 并且 |
or | 或者 |
in | 包含,相当于多个or(not in不在这个范围中) |
not | not可以取非,主要用在is 或in中 |
like | like称为模糊查询,支持%或下划线匹配 %匹配任意个字符 下划线,一个下划线只匹配一个字符 若需要转意,则在符号前加斜杠 |
SQL中的单行函数
Lower | 转换小写 |
upper | 转换大写 |
substr | 取子串(substr(被截取的字符串,起始下标,截取的长度)) |
length | 取长度 |
trim | 去空格 |
str_to_date | 将字符串转换成日期 |
date_format | 格式化日期 |
format | 设置千分位 |
round | 四舍五入 |
rand() | 生成随机数 |
Ifnull | 可以将null转换成一个具体值 |
- 用法:在字段名中用小括号括起来,填入函数名。
- 多行处理函数:
- select ifnull(comm,0) from emp;
列出津贴,若津贴为null则转换为0。
select ename,(sal + ifnull(comm,0))*12 as yearsal from emp;
列出所有人的年薪。
SQL中的多行处理函数
count | 取得记录数 |
sum | 求和 |
avg | 取平均 |
max | 取最大的数 |
min | 取最小的数 |
distinct | 去除重复 |
注意:多行处理函数自动忽略null
where关键字后面不能使用分组函数
使用方法:写出关键字然后加小括号,小括号中填入字符名。
select max(sal) from emp;
在emp表中找出薪水最高的人。
分组查询
- 主要涉及到的两个关键字:group by和having
- select sum(sal),job from emp group by job;
找出每个工作岗位的月薪总计
- 当一条SQl语句中含有group by的话,select后面只能跟有分组函数以及参与分组的字段。5以后的MySQL以及Oracle会报错。
- group by可以联合分组,后面跟多个字段名。
- having可以理解为,分组后再执行的where。
列出所有工作岗位的平均工资并降序排列
列出工资高于平均工资的员工
列出不同部门中,不同职业的最高月薪,并按照部门降序排列。
select job,deptno,max(sal) from emp group by deptno,job order by deptno desc;
找出每个部门的平均薪资,并且只显示平均薪资大于2000的数据。
连接查询
- 连接查询就是多张表联合取出数据,实际开发不会只有一张表。
- 只有一张表的话会造成数据冗余。就像一直重复一群人都是中国人一样。
- 链接查询的分类:
内连接:
等值链接、非等值链接、自链接
外连接:
左外链接、右外连接
全连接
按照年代分类:
SQL92(基本不用,老旧的语法)
SQL99(主流)
- 表的别名;
from 后面表的名字添加其他的字符串:elect e.ename,d,dname from emp e,dept d;
添加别名可以提高执行效率,让可读性更好
内连接
- 多表链接查询会出现笛卡尔积现象,也就是查询出来的结果是这几张表的记录条数之积。
- 避免笛卡尔积现象的方法:添加条件进行过滤
select e.ename,d.dname from emp e,dept d where e.deptno = d.deptno;(老语法)
等值连接:条件是等量关系的链接。(join on)
select
e.ename,d.dname
from
dept d
inner join(inner可以省略,但加上去可读性更好)
emp e
on
e.deptno = d.deptno;
非等值链接:就是连接条件不是比较是否相等
select
e.ename,s.grade
from
emp e
inner join
salgrade s
on
e.sal between s.losal and s.hisal;
- 将表emp连接至dept,on后面加连接条件。
- 这种语法比92好的原因是结构更清晰,连接条件与筛选条件分开,要对链接后的数据在进行筛选,后面可以添加额外的where关键字。
- 自链接:自己链接自己,一张表根据不同的数据看成两张表
需求:将表中的领导编号全部换为领导名字。
select
e.ename as ‘员工’, m.ename as ‘领导’
from
emp m
inner join
emp e
on
m.empno = e.mgr;
外连接
- 外链接与内连接的区别:
内链接没有主副之分,两张表中的数据不匹配就不显示。
外连接有主副之分,主要查主表,捎带查附表,数据匹配则一起显示,数据不匹配,则附表会模拟出null来匹配主表
- 外连接有左右连接之分,左连接有对应的右连接的写法,右连接也有相应的左连接的写法。
- 案例:
- 找出没有员工的部门(主表部门)
select
d.dname,e.deptno
from
emp e
right join
dept d
on
e.deptno = d.deptno
where
e.deptno is null;
- 找出所有员工,附带查询他们的领导(主表员员工,附表领导)
select
e.ename ‘员工’,m.ename ‘上级’
from
emp e
left join
emp m
on
e.mgr = m.empno;
多表查询
- 语法:就是多写几个join…on结构。
- 案例:
- 列出每一个员工的部门名称以及工资等级
select
e.ename,d.dname,s.grade
from
emp e
join
dept d
on
e.deptno = d.deptno
join
salgrade s
on
e.sal between s.losal and s.hisal;
- 列出每个员工的部门名称、工资等级以及上级领导的名字
select
e.ename,d.dname,s.grade,e2.ename
from
emp e
join
dept d
on
e.deptno = d.deptno
join
salgrade s
on
e.sal between s.losal and s.hisal
left join
emp e2
on
e.mgr = e2.empno;
子查询
- 子查询就是select语句嵌套select语句
- select的嵌套可以用于:
where、 from、 select关键字后面
- 案例:
- 列出每个部门平均薪水的薪资等级(P38)
select
a.dname,s.grade
from
(select avg(e.sal) avgsal,d.dname from emp e join dept d on e.deptno = d.deptno group by e.deptno) as a
join
salgrade s
on
- avgsal between s.losal and s.hisal
每个部门的平均薪水:
select
avg(e.sal) avgsal,d.dname
from
emp e
join
dept d
on
e.deptno = d.deptno
group by
e.deptno;
- 列出每个部门平均的薪水等级
select
avg(l.grade),d.dname
from
(select e.ename,s.grade,e.deptno from emp e join salgrade s on e.sal between s.losal and s.hisal) l
join
dept d
on
d.deptno = l.deptno
group by
l.deptno
;
每个人的薪水等级:
select
e.ename,s.grade,e.deptno
from
emp e
join
salgrade s
on
e.sal between s.losal and s.hisal
Limit
- limit是MySQL特有的,其他数据库不通用
- 作用是取出查询结果集的部分数据。
- 语法:
limit startIndex,length
stratIndex表示起始位置,从0开始。
length表示去多少个数据。
- 通用的标准分页SQL语句:
每页显示pageSize条记录
第pageNo页:
(pageNo – 1)*pageSize,paageSize
表操作
创建表
语法:
creat table 表名(
字段名1 数据类型 default 默认值,
字段名2 数据类型default 默认值.
字段名3 数据类型default 默认值,
……
)
ENGINE = 引擎名 DEFAULT CHARSET = 字符集名;
其中,引擎名默认是InnoDB,字符集名默认是UTF8。
若不使用default关键字,则默认值一般都是null
MySQL常用数据类型
类型 | 描述 |
Char(长度) | 定长字符串,存储空间大小固定,适合作为主键或外键 |
Varchar(长度) | 变长字符串,存储空间等于实际数据空间,最多可存储256个字符串。 |
double(有效数字位数,小数位) | 数值型 |
Float(有效数字位数,小数位) | 数值型 |
Int( 长度) | 整型 |
bigint(长度) | 长整型 |
Date | 日期型,对应Java中java.sql.Date类型 |
BLOB Binary Large Object | Binary Large OBject(二进制大对象) |
CLOB Character Large Object | Character Large OBject(字符大对象,最多可存储4G的字符串) |
其它………………… |
|
char与varhar的选择:
若要存入数据库中的数据是长度不会变的数据,如生日,性别等,可以使用char。
若存入数据库中的数据长度是不确定的,建议使用varchar,如姓名地址等。
BLOB以及COLB:
不能直接插入数据,要以流的方式放入数据。
BLOB可以用于存储图片,视频等。
CLOB可以用于存储简介等长度较长的字符串对象。
建表时候的表名:
一般以t_或者tbl_为开头,可读性更高。因为数据库中还有表以外的数据形识
删除表:
drop table if exists 表名;
如果表存在则删除该表。
插入、修改、删除数据
插入语法:
insert into 表名(字段名1,字段名2,字段名3……) values(值1,值2,值3……);
insert into 表名字 values(值1,值2,值3……);
insert into 表名字 select语句;
第二中写法中要注意值的顺序默认对应默认的字段名。
而再第一种写法中传入的值的顺序只需要对应传入的字段名。
第三钟写法是将查询结果插入表中。
在第一种写法中,若不传入对应的值,则表会插入在创建表时的默认值
注意:使用了insert关键字后,不能再次插入语句。只能使用update进行修改。
另外也可以一次插入多行数据,要在values关键字后面多用几个小括号传入数据即可。
修改语法:
update 表明 set 字段名1 = 值1,字段名2 = 值2……where 修改条件;
若不添加where关键字,则会修改表中所有的数据。
删除语法:
delete from 表名 where 条件;
若不添加where关键字,则会删除表中所有数据。
若要删除大表
truncate table 表名;
这种方式适合删除数据量很大的表,但这种删除方式不可回滚,数据永久丢失。
约束
- 创建表的时候,可以给表的字段添加相应的约束,添加约束的目的是保证数据的完整性、合法性以及有效性
- 常见的约束
- 非空约束(not null):约束的字段不能为null
- 唯一约束(unique):约束的字段不能重复
- 主键约束(primary key):约束的字段不能为null也不能重复
- 外键约束(foreign key):
- 检查约束(check):仅在Oracle数据库中支持的约束,MySQL不支持该约束。
- 列级约束:直接在字段后面加约束关键字
creat table 表名(
字段名1 数据类型 unique,
字段名2 数据类型not null.
字段名3 数据类型default 默认值,
……
);
- 表级约束:声明完字段名字后单独添加约束关键字以及要被约束的字段
creat table 表名(
字段名1 数据类型 default 默认值,
字段名2 数据类型default 默认值.
字段名3 数据类型default 默认值,
……
unique(字段名1,字段名2……)
);
主键约束(PK)
- 主键约束可以以列级约束或者表级约束的方式添加。
- 相关术语:
- 主键约束
- 主键字段
- 主键值
- 主键的作用:
- 表的三范式设计中有要求,每个表都应该有主键。
- 相当于一条记录在一张表中的唯一标识。
- 主键的分类:
- 按照数量分类:
- 唯一主键(推荐使用)
- 复合主键(多个字段联合起来做一个主键)
- 按照性质分类:
- 自然主键(与该表对应的业务无任何关系的自然数)
- 业务主键(主键值与表的业务有关联。比如银行卡号或身份证号做主键)
- 按照数量分类:
- 一张表的主键只能有一个
- 主键自增:
MySQL中支持主键自增机制,在primary key关键字后面添加auto_increment即可。
外键约束(FK)
- 添加语法:
foreign key(字段名) reference 父表名(字段名)
含义:该字段中的值全部引用与父表中的某一字段名。
- 相关术语:
- 外键约束
- 外键字段
- 外键值
- 外键的作用:
- 让一张表的子表的数据相对父表更具有规范性,有利于联合查询。
- 维护表之间的关系,保证参照的完整性。
- 一个表的外键必须来源于父表的主键,或者是被修饰为不可重复的字段。
- 外键字段可以为null,但不推荐设置为null。
- 联合查询时,一般会以表的外键来进行连接。
事务
- 事务的定义:
事务是完整的逻辑单元,不可再分。
比如要执行两条同时成功或失败的DML语句,不可再分,必须同时成功或失败。
那么这两条DML语句就是一个不可再分的完整逻辑单元。
- 与事务相关的语句只有DML语句,因为DML语句与数据库中的数据的安全有直接的关系。为了保证数据的准确性、完整性、安全性,我们需要使用事务机制。
- 相关术语:提交commit、回滚rollback、保存点savepoint
- 事务机制的应用是建立在多条DML语句同时执行的前提上的。
- 事物的特性(ACID):
- 原子性Atomicity:事务是最小的工作单元,不可再分。
- 一致性Consistency:保证事务中的DML语句必须同时成功或失败,事务前后数据 的完整性必须一致
- 隔离性Isolation:不同的事务间具有隔离。
- 持久性Durability:数据最后必须要持久化到硬盘中,事务才算结束。
- MySQL中的的事务默认是自动提交的。执行任意一条DML语句就会提交。
关闭自动提交则要输入start transaction来开启事务,事务结束后要重新输入。
事务结束前可以使用rollback进行回滚。
事务的隔离级别
设置事务的全局隔离级别:
set global transaction isolation level 级别名称;
需要重新登陆才会生效。
查看隔离级别:
老版本:select @@global.tx_isolation;
新版本;select @@global.transaction_isolation,@@transaction_isolation;
第一级别:读未提交read uncommitted
即对方事务尚未提交的数据,当前事务可以读取到。
容易发生脏读(Dirty read)现象,表示读到了脏数据。
这种级别基本不用。
脏数据:脏数据表示的是另一个事务的临时数据,这种数据极不问题,当另一事务的数据提交或回滚后,脏数据就会变化。依据脏数据所作的操作是不正确的。
第二级别:读已提交read committed
对方事务提交后的数据才可以被我方事务读取到。
这种方式解决了脏读现象。
但没有解决不可重复读的问题。
这种级别是主流的安全级别,适用于大多数系统。
不可重复读:事务A首先读取了一条数据,然后执行逻辑的时候,事务B将这条数据改变了,然后事务A再次读取的时候,发现数据不匹配了,就是所谓的不可重复读了。简单地说就是别的事务会影响当前事务的数据,导致当前事务对数据执行逻辑的时候,每次读到的数据可能会不一样。
第三级别:可重复度repeatable read
读取数据前会对当前数据作备份,只读取备份的数据。
因为每次读取的都是自己备份的数据,所以解决了不可重复读得问题。
但没有解决幻读 (phantom read)问题。
资源消耗较高的级别,带来了更多的性能消耗。
幻读:事务A首先根据条件索引得到N条数据,然后事务B改变了这N条数据之外的M条或者增添了M条符合事务A搜索条件的数据,导致事务A再次搜索发现有N+M条数据了,就产生了幻读。
第四级别:序列化/串行化读
所有事务排队执行,最严格的级别。
解决所有问题。
资源消耗最大的级别。
索引
- 索引的概述:
索引相当于一本书的目录,可以快速定位数据资源。在数据量庞大的时候快速检索。
查询一张表的时候有两种方式:全表扫描、依据索引检索。
- 缩小了扫描范围是索引提高检索效率的根本原因,底层使用的数据结构是B+Tree(多路搜索树)。
- 使用索引要考虑多方面因素,因为数据一旦改动,索引是要重新维护的,消耗维护成本。
- 适合添加索引的环境:
- 数据量相对庞大
- 添加索引的字段极少进行DML操作,避免索引维护。
- 添加索引的字段常出现在where子句中。
- 注意:主键以及具有unique约束的字段自动添加索引。
- 查看当前SQL的执行计划:
explain SQL语句;
在出来的表格中的type字段中可以看到扫描类型,all为全表扫描。
表格中的rows字段可以查看检索了多少条数据。
- 给字段添加索引;
creat index 索引名称 on 表名(字段名);
- 删除索引:
DROP INDEX 索引名称 ON 表名;
- 实现原理:
当添加索引后,会在索引所在字段生成一个地城实现了排序分区的B_tree数据结构的排序表。索引会获取数据在表中的“物理地址,检索到数据后返回相关的物理地址,直接通过物理地址定位到硬盘中的相关数据,以获得更高的效率”
- 索引的分类:
- 单一索引:单个字段添加索引
- 复合索引:多个字段联合添加一个索引
- 主键索引:主键上自动添加索引
- 唯一索引:有unique约束的字段自动添加索引
10、索引失效:
当使用模糊查询,且第一个通配符使用的是“%“,此时索引失效,只能使用全表扫描。
视图
- 视图是一种以不同方式看待表的方法。有时候也被称为虚拟表,但是对视图进行CRUD会影响原表中的数据。
- 视图的作用:
- 通过简化,访问数据变得简单
- 对不同用户展示不同的内容
- 隐藏表的具体细节,只展示表的大致结构。(面向视图检索)
- 创建视图:
create view 视图名 as DQL语句;
创建视图只能通过DQL语句进行创建。
可在DQL语句中对字段进行改名以实现隐藏原表字段名的效果。
- 删除视图:
drop view 视图名;
- 视图的CRUD:
与对表的CRUD相同,将from后的表名改为视图名即可。
6、通过视图查询不会真正意义上的提高检索效率,真要提高还得看索引.。
DBA命令
- 常用于导出导入数据进行数据备份以及数据转移。
- 导出:(在dos命令窗口中执行)
- 导出整个数据库:
mysqldump 数据库名>导出路径以及文件名.sql -u用户名 -p密码
mysqldump sinot> D:\JAVA\sinot.sql -uroot -p159326
- 导出数据库中的某个表:
mysqldump 数据库名 表名>导出路径以及文件名.sql -u用户名 -p密码
mysqldump sinot demp> D:\JAVA\sinot_demp.sql -uroot -p159326
- 导入:
- 先创建数据库并使用
- source sql脚本所在路径;
三范式
- 设计范式,就是设计表的依据,主要目的是减少数据冗余。
- 三范式的的第二范式建立在一范式的基础之上,第三范式建立在第二范式之上。
- 一范式:
任何一张表都要有主键,且每个字段都有1原子性,不可再分。
- 二范式:
所有非主键字段要完全依赖主键,不能产生部分依赖。
多对多,三张表,关系表有两外键。
- 三范式:
所有非主键字段要直接依赖主键,不能产生传递依赖。
一对多,两张表,多的表要加外键。
- 提醒:设计表是并不是一定要完全遵守三范式,表的联合越多,查询效率越低,有时候需要牺牲数据库空间以获取查询速度,主要以客户需求为主。
- 一对一的设计
- 主键共享:两张表公用一个主键,其中一张表的主键既有外键约束也有主键约束。
- 外键唯一:两张表都有各自的主键,其中一张表有单独的外键,该外键以另一张表的主键作父表字段名,并且添加unique约束。也就是一对多的设计,表额外加了唯一性约束变为一对一的设计。
注意:
SQL语句都是以分号结尾
SQL语句不区分大小写
SQL中字符串用单引号括起来
count(*)与count(字段名)的区别:加星号代表计算某个字段的总记录条数,加具体字段名代表计算该字段名中不为null的数据数量。
只能用于所有字段名前。