引入:
查看 MySQL 的运行情况常用指令
用来查看 MySQL 服务端进程是否启动
ps ajx | grep mysqld
停止 MySQL 服务端进程
systemctl stop mysqld
启动 MySQL 服务端进程
systemctl start mysqld
重启 MySQL 服务端进程
systemctl restart mysqld
查看 MySQL 服务,默认端口号 3306
netstat -nltp管道和 xargs 配合使用,可以将上一个命令的结果作为下一个命令的参数
find . -name "*.tmp" | xargs rm -f
MySQL 的配置文件存储在 /etc/my.cnf,后面的编码格式、校验集可以在这里更改。储存的表数据在 /var/lib/mysql/ 目录下
mysqld 作为服务端例程存在于 /sbin/mysqld ,mysql 作为客户端存在于 /bin/mysql
登录方式
- MySQL 默认 root 登录没有密码
或者打开 MySQL 配置文件
vim /etc/my.cnf
#在 mysqld 最后一栏加入:skip-grant-tables
#保存后退出,重启 MySQL 服务
systemctl restart mysqld指定用户登录
- Ubuntu 下的配置文件
注:贴图方式了解mysql使用方法
一、MySQL 概述
MySQL 和数据库
狭义的数据库是存放在磁盘、内存中,按照特定结构组织的数据文件。广义的数据库是数据管理系统,有一套完整的数据存储解决方案(如 MySQL)。
与普通文件相比,普通文件只能完成基础数据存储,缺少数据管理能力。数据库屏蔽底层文件操作,用户只需要提供查询条件,由服务程序完成磁盘读写并返回结果,具有高效的数据管理能力。
MySQL 客户端向网络发送 SQL 语句,MySQL 的服务进程接收后读写磁盘上的数据库文件,结果返回客户端。
MySQL 是基于 C/S 模型,用于存储与管理数据的网络服务程序。
二、SQL 语言基础
2.1 数据库、表、字段、记录等核心概念
表的增删查改CURD:create,retrieve,update,delete
创建表:添加comment描述字段

查看表以及对表属性描述



修改表





删除表

向表插入








2.2 数据类型(数值、字符串、日期时间)
在mysql中有很多约束,防止插入不合法数据,保证数据库中的数据可预期,完整的
| 类型 | 字节 | 取值范围(有符号) | 取值范围(无符号) | 用途说明 |
|---|---|---|---|---|
TINYINT |
1 | -128 ~ 127 | 0 ~ 255 | 极小整数,可用做状态(0/1) |
SMALLINT |
2 | -32768 ~ 32767 | 0 ~ 65535 | 小整数 |
MEDIUMINT |
3 | -8388608 ~ 8388607 | 0 ~ 16777215 | 中等整数 |
INT / INTEGER |
4 | -2147483648 ~ 2147483647 | 0 ~ 4294967295 | 最常用普通整数(id 首选) |
BIGINT |
8 | -9223372036854775808 ~ 9223372036854775807 | 0 ~ 18446744073709551615 | 超大整数,雪花 ID 使用 |
FLOAT |
4 | -3.402823466E+38 ~ 3.402823466E+38 | --- | 单精度浮点数,不适合金额 |
DOUBLE |
8 | -1.7976931348623157E+308 ~ 1.7976931348623157E+308 | --- | 双精度浮点数 |
DECIMAL(m,d) |
可变 | 由精度定义 | --- | 定点数,金额、财务精确计算,m 总长度,d 小数位 |
tinyint


bit位




float
float(m,n)[unsigned]:m指定显示长度,n指定小数位数







decimal
注:float表示的精度大约7位,decimal整数最大位数65,支持小数最大位数30。整数部分缺省值10,小数部分缺省值0
char
注:char(L),最大长度值255
varchar变长字符串
varchar(L),L表示字符长度,最大长度65535字节
- varchar有1-3个字节用来记录数据大小,当表的编码utf8时,varchar可以存储(65535-3)/3个字符,如果是gbk,参数最大是(65535-3)/2个字符
- 当表内含有其他字段时,可以保存的字符只会更小
优缺点:
- 定长的磁盘空间比较浪费,效率高
- 变长的磁盘空间比较节省,效率低

日期和时间类型




enum和set






enum和set类型查找



- 2.3 DDL(数据定义语言---对表的操作)
客户端发起建立数据的操作,mysqld服务帮我们在Linux服务器建立表结构,实则建立数据库是在linux下创建目录存在于/var/lib/mysql/,在数据库内建表也是在目录下创建文件,只不过这个动作由mysqld完成,客户端下达指令。
此外,SQL指令不区分大小写


创建数据库时有两个编码集
数据库编码集:规定字符在磁盘内存中用什么格式存储
数据库校验集:支持数据库进行字段比较时使用的编码,也是一种读取数据库中数据的采用的编码格式
**总结:**数据从客户端发出,经过网络传输存入数据库磁盘,整个流程中所有环节字符编码必须保持统一,否则字符二进制解析失败,产生中文乱码。
查看系统的编码集和校验集

查看不止数据库的校验集

- 查看数据库支持的字符集(向数据库写入的):show charset
- 查看数据库支持的全局字符校验规则(从数据库读取):show collation

验证校验集对查找的影响,一个区分大小写,一个不区分。校验集还会影响排序




使用alter修改数据库


数据库备份和恢复


#如果备份的是其中一张表
mysqldump -u root -p 数据库名 表1 表2 > xx.sql
#同时备份多个数据库
mysqldump -u root -p -B 数据库1 数据库2 > 数据库存放路径
##如果备份一个数据库没有带上-B参数,在恢复数据库时,需要先创建空数据库,然后使用数据库,再用source还原
查看当前数据库的连接情况

2.4 DML(数据操作语言)
- INSERT、UPDATE、DELETE




delete



Truncate
- Truncate不会把自己的操作包装成事务,记录到bin log是DDL(数据定义语言)语句本身,mysql持久化方式通过记录历史sql语句,高版本mysql默认时bin log开启 ,通过两个数据库主从同步,记录sql语句。delete是DML(数据操作语言)语言支持事务和回滚,truncate不支持回滚
- 特点:
- truncate只能对整表操作,不能像delete一样对针对部分数据操作
- 会重置auto_increment锁
- truncate在删除数据时,不经过真正的事务,无法回滚
- delete不会清auto_increment会更新日志,Truncate直接清除auto_increment,不更新日志


删除原表中的重复数据
创建一个和原表结构相同的表---将原表不重复数据插入新表---新表重命名



说明:
- rename只需要更改文件名,与插入修改相比更高效,如果目录下有正在被访问的文件,先把修改后的文件准备好,在rename生效,效率高。
- 这个过程类似上传大文件时,先上传到临时目录,再移动到指定路径下。移动的效率是高的,move操作只需要改变inode对应的映射关系
聚合函数






分组聚合统计
分组在逻辑上把一张表分成多个子表,然后对各自的子表进行聚合统计,关键字是group by



- having和where的区别在于条件筛选的阶段不同,where对原表筛选,having对子表筛选
- mysql下一切皆表,select出来的临时结果也是一张表,处理好单张表的CURD,就能迁移到多张表的CURD

函数
时间函数





字符串函数













trim的使用常见于用户名密码登录,限制空格输入
数学函数

其他函数
- select user()查询当前用户
- select md5(str)对一个字符串进行md5摘要,摘要后得到一个32位字符串



-
select database()显示正在使用的数据库
-
select password('......')mysql数据库使用该函数加密
-
select ifnull(val1, val2) 如果val1为null,返回val2,否则返回val1的值
-
SELECT(基础查询)
- 通常情况下不适用*进行全列查询:查询的列多,需要传输的数据量大。可能影响到索引的使用---select * from 表名称;

查询字段为表达式


复合查询





子查询
select查询中允许再有select子句,将子句的返回结果作为条件,也叫嵌套查询


多行子查询
使用关键字:
- in(判断某个值是否等于子查询返回结果集中的任意一个值)
- any(将外部查询的值与子查询返回的每一个值进行比较。只要与其中任意一个值满足比较条件,整个条件就为真)
- all(将外部查询的值与子查询返回的每一个值进行比较。必须与子查询返回的所有值都满足比较条件,整个条件才为真)
子查询不仅能出现在where也能出现在from



多列子查询
寻找有多个列属性匹配的数据


在from子句中使用子查询





合并查询





2.5 DQL(数据查询语言)
#### WHERE 条件过滤








-
ORDER BY 排序
查询到结果后进行排序,order by column asc\|desc,asc为升序,desc为降序



这里可以使用别名因为先执行from,在where,然后查找属性name,math+......,最后才排序,而在第三步就定义了别名,所以后面的order by可以用别名


-
GROUP BY 与聚合函数(COUNT, SUM, AVG, MAX, MIN)
HAVING 分组后过滤
LIMIT 分页
对未知表查询时,最好加limit 100,避免因为表中数据过大,查询全表数据导致数据库卡死




2.6表的约束
- 非空属性和空属性
NULL代表什么也没有,不参与运算。select支持算术运算


-
default约束

- default:如果设置了,用户将来插入具体数据就用用户的,没有就用默认的
- default和not null不冲突,相互补充。用户插入null使用default的数据,插入具体数据时用该数据


-
comment
comment相当于注释---描述列属性


-
zerofill
zerofill自动根据宽度补零


int后面括号数字的含义

-
主键约束
- 主键
primary key用来唯一约束该字段里面的数据,不能重复,不能为空,一张表中最
多只能有一个主键,主键所在的列通常整数类型。






-
-
复合主键
-

-
-
自增长
-




-
唯一键
- 一张表中往往很多字段需要唯一性,数据不能重复,但是一张表中只能由一个主键,唯一键可以解决表中有多个字段需要唯一性约束的问题
- 唯一键和主键类似,唯一键允许为空,而且可以多个为空
- 主键是标识唯一性的,唯一键保证在业务上不和别的信息出现重复




-
外键
- 外键用于定义主表和从表之间的关系,外键约束主要定义在从表上,主表必须有主键约束或unique约束,当定义外键后,要求外键列数据必须在主表的主键列存在或为null



2.7 多表查询
-
- 笛卡尔积---穷举

-
INNER JOIN
内连接:利用where子句对两种表形成的笛卡尔积进行筛选
第一种多表查询:from后面跟两张表,用一表的deptno=二表的deptno建立连接,去除冗余数据

第二种内连接查询:

-
- LEFT/RIGHT JOIN
左外连接:联合查询,左边的表完全显示,没有的信息设为null

右外连接:右边的表完全显示,包含null


-
自连接
本质是连接两张相同的表


三、索引与查询优化
3.1 索引原理与数据结构(B+Tree)
- mysql服务器本质在内存中,所有数据库的CURD操作全部在内存中进行
- 提高算法效率的因素:使用的数据结构,算法本身
- 索引通过改变组织数据的方式加快数据的搜索
在面对大量数据时,直接执行下面语句时,查询耗时极长
解决方法是对empno字段添加索引
Mysql作为应用软件,可以想成一种特殊的文件系统,有着更高的IO场景,为了提高基本的IO效率,mysql进行IO的基本单位是16KB,而在操作系统内部,页框大小位4KB。mysql先将数据从应用层缓冲区打入到内核级缓冲区,再由操作系统打入到磁盘

#可以通过以下sql语句查看
show global status like 'innodb_page_size';
结论:
- mysql中的数据文件以page为单位保存在磁盘
- CURD操作都需要计算,找到对应位置
- 任何计算的操作都需要CPU从内存读取数据,数据需要转移到内存中
- 在特定时间内磁盘和内存中包含相同的数据,两者之间的交互涉及IO,IO基本单位是page(4*4KB),IO次数越少效率越高
- mysql服务器在内存运行时,在服务器内部申请了Buffer Pool的大内存空间,用来缓存数据。一次写128M数据和128次写1M数据相比效率更高,因为分配的扇区位置是连续的,且有数据局部性原理

- 向一个有主键的表中乱序插入数据后会自动排序
- 原因在于mysql内部存在大量的page也就决定了需要数据结构管理这些位于Buffer Pool 的page,B+树在Buffer pool中按需加载
- 在innodb存储引擎下采用B+树,聚簇索引(用户数据和索引数据放在一起的方案)
- 非叶子节点不存数据可以存更多目录项,保证搜索效率
- 叶子节点通过双向链表连接可以范围查找
- 建表时会有隐藏字段,如果没有主键,则使用隐藏的ROW_ID,得到的结果按照插入时候的顺序,建议不要使用ROW_ID
- 目录页只存放各个下级Page的最小键值,查找的时候只需要自顶向下查找,将加载部分目录页加载到内存,减少IO次数
选用B+树的原因
MyISAM非聚簇索引
MyISAM存储引擎使用B+树,但叶子节点保存数据记录的地址,图中第一列为主键

3.2 索引类型(主键索引、普通索引......)
普通索引
Mysql除了默认建立主键索引外,用户也有可能建立按照其他列信息建立的索引,叫做辅助(普通)索引
innodb的非主键索引中叶子节点没有数据(节省空间),只有对应记录的key值。首先检索辅助索引获得主键,然后利用主键到主索引中检索获得记录,这个过程是回表查询
全文索引
- 面对文章字段需要检索,使用全文索引。Mysql中要求储存引擎必须M有ISAM,而且默认全文索引支持英文,不支持中文,想要支持中文需要装sphinx的中文版插件(coreseek)
- MyISAM支持高并发,专门全文索引,但不支持事务
- Inodb支持事务
- FULLTEXT(title,body)建立全文索引





3.3 索引创建、查看与删除
- 频繁作为查询条件的字段做索引
- 唯一性太差或者更新频繁的字段不适合做索引
- 不出现在where子句的字段不适合做索引

- 主键索引就是建立主键,一般是int类型

普通索引创建

查询索引
- show keys from 表名
- show index from 表名
- desc 表名



去掉、增加索引




复合索引
- 用多列构成的索引是复合索引,当高频查找值时,通过name查找email构成复合索引,不再需要回查
- 使用name在B+树中查找,从左向右匹配(索引匹配),匹配到直接返回邮箱(索引覆盖),不再需要回查





















