选择mysql理由
低成本,高效能
通用,易安装,易使用
mysql架构
应用层:负责和客户端,用户进行交互,需要和不同的客户端和中间服务器进行交互,建立连接,记住连接状态
,响应状态
逻辑层:负责具体的逻辑查询,事务管理,存储管理,恢复管理,以及其他的附加功能
查询处理器负责查询的解析,执行;
接到查询请求时,数据库分配线程来处理它,先由查询处理器生成执行计划,然后交由计划执行器来执行;
由事务管理器来执行ACID特性;
锁管理器控制并发
物理层: 实际物理磁盘上的数据库文件,比如数据文件,日志文件。
mysql查询执行过程概述
客户端发布查询的流程如下,首先连接MYSQL(Connection Handling),然后发布查询,如果缓存(query ache)有结果集,则直接返回,如果没有,Mysql解析查询(Parser)将通过优化器Optimizer生成执行计划,然后执行执行计划通过API(Pluggable Storage Engine API) 从存储引擎获取数据,并返回给客户端
什么是执行计划, 执行计划就是一系列操作步骤,sql是声明行语言,只需要告诉数据库查什么,不告诉数据库如何去查,数据库要做的就是基于算法和统计信息来计算最佳访问路径。
相关概念
短连接
程序和数据库建立连接,操作后,关闭连接;
基本步骤:连接-数据传输-关闭连接
对于高并发业务,如果碰到连接的冲击,推荐使用长连接和连接池.
长连接
程序建立连接之后,就一直打开,被后续程序重用,尽管 mysql 连接比其他数据库快得多
连接池
数据库创建和销毁连接的开销很大,可以使用连接池改进性能,
将所有连接的客户端共享使用,连接池可以加速连接,也可以减少数据库连接,降低服务器的负载
持久连接和连接池的区别
长连接是一些驱动,驱动框架, ORM 工具的特性,由驱动来保持连接句柄的打开;
连接池是应用服务器的组件,可以通过参数来配置连接数,连接检测,连接的生命周期;
如果连接池或者长连接的使用的连接数过多,有可能超过数据库实例的限制.
单点故障: 系统某个部分,一旦失败,将会导致整个系统无法工作。一般需要增加冗余系统,消除故障
读写分离:数据库只能接受有限的读请求,对于读请求很多的应用,数据库可能会成为瓶颈,为了增加读的能力,引入读写分离的技术,比如利用复制技术配置多个从库
相关基础概念
数据模型:数据的定义和格式,数据是如何组织的,关系数据模型以二维表结构表示实体与实体之间的关系
schema:定义语言描述的数据结构,定义数据是如何组织构建的。典型的关系数据模型,是以数据库表的形式来组织数据的,关系数据库的schema就是数据库各种关系的结构化描述。
结构化数据:记录信息的类型,格式等属性是固定的。业内也有人把关系型数据中能用二维表表示的数据成为结构化数据
DDL:数据定义语言,负责数据结构定义与数据库对象定义的语言,例如创建数据库,创建表,create、alter,drop
DML : 数据操作语言,用来查询和修改数据的语句
关系数据模型: 关于null,字段未知或者未定义,数据库小心处理;数据库管理系统为了高效地检索记录,往往会创建各种索引结构加速检索记录,或者按照索引 /key 的顺序存储记
录,所以基于记录的索引 /key 会很容易查找到记录。
XML数据模型:可扩展标记语言
JSON:储存半结构化数据
ER建模:实体(对象集合),关系(实体之间关系),属性
数据类型
数值类型: 整型和实数
确切精度类型:decimal
近似精度类型:单精度float,双精度double
整型: TINYINT/SMALLINT/MEDIUMINT/INT/BIGINT/ 空间占用依次增大,数值范围依次变大
decimal和numeric:定点数,小数点后面的位数是固定的,DECEMAL(M,D)M是精度,10进制数位数,D是标度表示小数点后的位数。
FLOAT和double:浮点数比整型数值范围更大,单精度四个字节,双精度8个字节,浮点数存在误差问题,尽量不使用浮点数进行比较,
日期和时间类型:表示时间值和时间类型有DATETIME,DATE,TIMESTAMP,TIME,YEAR,每种类型有其特有范围,timestamp有特有自动更新特性,
DATETIME:8个字节,同时包含日期和数字
DATE:只有年月日日期,3个字节
TIMESTAMP 时间戳,列用于在进行 INSERT 或 UPDATE 操作时记录日期和时间,保存格式和DATETIME相同,以4字节保存,以UTC格式保存,存储时保存当前时区信息,
若将 TIMESTAMP 类型字段定义为 default current_timestamp ,那么插入一条记录时,该 TIMESTAMP 字段自动被赋值为当前时间;
若将 TIMESTAMP 类型字段定义为 on update current_timestamp ,那么修改一条记录时,该 TIMESTAMP 字段自动被修改为当前时间;
字符串类型:CHAR/VARCHAR/BINARY/VARBINARY/BLOB/TEXT/ENUM/SET
CHAR和VARCHAR:类型类似,保存和检索数据的方式不同,声明方式char(30),表面占用字符位数,超过位数则对其裁剪,char存储固定长度字符,存储时右边会增加指定空格达到指定字符长度,检索时会去掉,适合保存长度差不多的字符串,varchar变长字符,适合存储长文本。
选择合适数据类型:
小往往更好,简单类型更好,尽可能避免null值,
mysql 复制架构
主从模式 A→B
主主模式 A←→B
链式复制模式 A→B→C
环形复制模式 A→B→C→A
存储引擎介绍
mysql存储引擎是可插拨的,其核心代码和存储引擎是分离的,mysql支持不同的表使用不同的引擎
InnoDB 引擎
优点:
灾难恢复性好;
支持全部4种级别事务,默认事务隔离级别,可重复读;
使用行级锁;
数据物理组织形式是簇表,数据按主键来组织,主键和数据是一起的;
实现缓冲管理,缓冲索引和缓冲数据,自动创建散列索引加快数据获取;
支持外键;
支持热备份
如何安装
mac 安装下载社区版本5.7
安装时显示临时密码:root@localhost: 1I3!6+2oG;S! 随机
配置文件
/usr/local/mysql-5.7.17-macos10.12-x86_64/support-files/my-default.cnf
配置文件主要参数设置
innodb_buffer_pool_size 提升性能,将数据先在缓冲区合并
innodb_log_file_size 每个日志文件的大小,建议将日志文件大小设置为256mb 或者更大,这样可满足需要
innodb_flush_log_at_trx_commit,建议设置为2
这个选项的默认值是1。当设置为2时,在每个事务提交时,日志缓冲被写到文件中,但不对日志文件做刷新到磁盘的操作,对日志文件刷新每秒刷新才发生一次
sync_binlog 建议设置为0,值为1是最好的选择
日志文件
命令文件夹
/usr/local/mysql-5.7.17-macos10.12-x86_64/bin
常用命令行使用
mysql 命令行
启动MySQL服务
sudo /usr/local/mysql/support-files/mysql.server start
停止MySQL服务
sudo /usr/local/mysql/support-files/mysql.server stop
重启MySQL服务
sudo /usr/local/mysql/support-files/mysql.server restart
mysql -h localhost -P 3306 -u root -p 登录
show databases;显示所有数据库
help;
mysql> SELECT VERSION(), CURRENT_DATE; 查看版本,目前日期
mysql> SELECT SIN(PI()/4), (4+1)*5;
use db_name; 使用数据库名称
select database(); 查看正在使用的数据库
create database db_name; 创建数据库
GRANT select,insert,update,delete ON db_name.* TO 'your_name' @ 'your_client_host';
show tables; 显示所有的表
status 显示当前连接,客户端,数据库字符集等信息的命令;
SHOW ENGINES;显示可用搜索引擎
exit 退出
mysql -h localhost -P 3306 -u root -p employees < /Users/lx/Downloads/employees.sql
输入密码导入数据
整个数据库数据导出到文件
mysqldump -h localhost -u root -p mydb >e:\mysql\mydb.sql
单个表导出到文件
mysqldump -h localhost -u root -p mydb mytable>e:\mysql\mytable.sql
将数据库mydb的结构导出到e:\mysql\mydb_stru.sql文件中:
mysqldump -h localhost -u root -p mydb --add-drop-table >e:\mysql\mydb_stru.sql
sql语法
(1)模式匹配:SQL 有两个通配符, “-” 匹配任意单个字符, “%” 匹配任意多个字符(包括 0 个字符)
( 2 )逻辑操作符与或非( AND 、 OR 、 NOT )
(3 )范围操作符 IN 和 BETWEEN
( 4 )限制获取记录数(使用 LIMIT 子句)
( 5 )排序( ORDER BY )
( 6 )数据计算
( 7 )使用 DISTINCT 获取不重复的唯一值,SELECT DISTINCT first_name FROM employees ;
( 8 )聚集函数 COUNT 、 MIN 、 MAX 、 AVG 、 SUM
( 9 )分组统计 GROUP BY 子句
( 10 )并集操作( UNION 和 UNION ALL ) UNION 实际上是 UNION DISTINCT ,在进行表连接后会筛选掉重复的记录,SELECT * FROM a
UNION ALL
SELECT * FROM b;
( 11 ) NULL 值,NULL 值的判断一般使用 IS NULL 或 IS NOT NULL ,不能使用以上的比较操作符 = 、 < 、 > ,因为 NULL 是一个特殊的值
JOIN (连接)
链接原理:全表扫描驱动表,用驱动表结果集去匹配被驱动表,可以利用索引,数据库基于成本会选择小表作为驱动表,然后被驱动表使用索引进行连接。
连接的表越多,函数嵌套的层数就越多,尽量减少连接表的个数;
子查询:查询语句里面的select语句,子查询不宜过多,否则性能会很差。
索引学习
数据库索引,是数据库排序 的数据结构,用于协助快速查询,更新数据表中的数据。
mysql支持索引:B树索引,散列索引,空间索引,全文索引
从逻辑上,可以分为单列索引,复合索引(多列索引),唯一索引,和非唯一索引
如果索引键值的逻辑顺序与索引所服务的表中相应行的物理顺序相同,那么该索引被称为簇索引( cluster index ),也称为聚集索引。
InnoDB使用聚集索引,数据和索引在一起,记录被真实的保存在索引的叶子中。
簇索引优点:
1,将相关数据保持在一起,叶子节点内可保存相临近的记录;
2,因为索引和数据存储在一起,所以查找数据通常比非簇索引更快
何种查询使用索引
1,支持前导列,筛选记录where条件能组合复合索引最左边的部分,既按最左前缀原则进行筛选。
2,索引列上范围查找,where betweenand 条件在索引列上,范围不要太大,in()不属于范围查找的范畴。
3,where子句的条件列是复合索引前面的索引列再加上紧跟的另一个列的范围查找,举例:CREATE INDEX idx_a_b_c_d ON tb1(a,b,c,d);只有使用如下条件才能应用到复合索引WHERE a=? AND b=? AND c > 10000; WHERE a=? AND b=? AND c=? AND d<10000;
进阶
应用程序性能指标(应用性能管理 APM)
两组
终端用户性能体验:负载和响应时间
负载是应用程序处理的业务量,如每秒事务数,每秒请求数 qps,每秒 PV.
响应时间是指给定的负载下,应用程序响应用户的操作时间
第二组性能指标:一定负载下,应用程序使用的计算资源是否有足够的容量来支持给定的负载,预测在哪里可能会有性能瓶颈
研发技巧(mysqlDBA 修炼之道)
* 存储树形数据,比如组织架构,话题讨论,知识管理,商品分类
①路径枚举,增加一个字段,记录节点祖先信息
②闭包表,记录节点之间的关系,记录节点和父节点之间关系,也记录所有节点之间关系
* 转换字符集
需要修改某个表的字符集.比如 A表的字符集原来是 gbk, 现在将其修改为 utf-8
①直接 mysql命令下完成;
②使用 mysqldump 工具
③使用 ICNV命令转换文件编码
* 处理重复值
①防止出现重复记录:主键或者唯一索引,插入时使用 insert ignore 语句,不重复正常插入,重复舍掉;也可以 replace into 语句,新记录则插入,重复记录则替换.
②统计和识别重复值;
SELECT COUNT (*) AS repetitions, last_name, first_name FROM person_tbl
GROUP BY last_name, first_name HAVING repetitions > 1;
③从结果集中消除重复记录
使用 DISTINCT
* 分页算法
mysql> SELECT col_1,col_2 FROM profiles WHERE sex='M' ORDER BY rating limit 100000, 10;
大偏距值查询很慢,方法:限制用户看到的页,比如只提供最新的几页
覆盖索引
查询优化技巧
优化策略
优化数据访问:可以缓存就不需要从数据库读取
重写 sql:复杂查询严重降低并发性,建议将复杂查询分为多个简单查询;连接 join 严重降低并发性.
重新设计表:可以增加缓存表,暂存统计数据,增加冗余列,减少连接
添加索引:生产环境80%性能问题是性能问题.
group by/Distinct/order by 语句优化
* 尽量对较少的行进行排序;
* 如果连接多张表, order by 列应该属于连接顺序的第一张表
* 利用索引排序
* groupby,orderby 语句参考的列应该尽量在一张表上,如果不在,可以考虑冗余一些列,要么合并表
* 指定 order by null: 默认 mysql 排序所有 group by 的查询,为避免排序带来消耗,可以指定 order by null
优化 limit 字句 效率差 两点:
1)限制页数,只显示前几页,查过也术后,直接显示更多( more)
2)避免设置 offset 值,也就是避免丢弃记录,可以使用条件限制要排序的结果集
索引
索引中字段不超过5个
单张表索引数量建议控制5个以内
唯一键和主键不要重复
索引字段的顺序需要考虑唯一值得个数,选择性高的字段一般放在前面
复合索引的前面部分用于等值查询,后面的部分用于排序
使用 explain 判断 sql 语句是否合理使用了索引,尽量避免 Extra 列出现 Using File Sort,Using Temporary
UPDATE,DELETE 语句需要根据 WHERE 条件添加索引(啥意思)
建议不要使用 like%value 的形式, mysql 仅支持最左前缀索引
对长度过长的 VARCHAR 字段,比如网页地址建立索引时,需要增加散列字段,对varchar 使用散列算法后,散列后字段最好是整型,然后对该字段建立索引.
覆盖索引,覆盖索引一般常驻于内存中,因此可以大大提高查询效率;
把范围条件放到复合索引的最后,WHERE条件中的范围条件(BETWEEN、<、<=、>、>=)会导致后面的条件使用不了索引.
表设计
尽量将字段设置成 not null ,null值存储需要额外空间,且会导致比较运算较为复杂,这会使优化器难以优化 sql
使用更短小的列,比如短整型,短整型执行速度往往更快
存储精确浮点数时,使用decimal 替代 float 和 double
建议使用 unsigned 类型存储非负值
建议使用 INT unsighed 存储 IPV4
整型定义中不添加显示长度的值,比如使用 int, 而不是 int(4)
建议不要使用 ENUM 枚举类型
尽可能不要使用 TEXT,BLOB 类型
字符集建议使用 UTF-8
存储年时使用 YEAR 类型
存储日期时使用 DATE 类型
存储时间时建议使用 TIMESTAMP 类型,
join 字段在不同表上类型和命名要一致
- 常见问题