保存数据的格式(技术),不一样格式体现特性不同 php
myisam mysql
① 结构、数据、索引 文件单独存储 redis
② 存入数据顺序(不考虑主键顺序) ,写入数据速度快 算法
③ 并发性,低,锁整张表 spring
④ 压缩机制 sql
innodb 数据库
① 结构有单独文件,数据和索引合并到一个文件中 缓存
(经过设置,能够给每一个表设置一个"数据/索引"文件) 服务器
② 存入数据顺序(给考虑主键值的前后顺序,数值大小排序存储) 数据结构
③ 并发性,高,锁行
① 字段选取占据空间小的(bigint int mediumint smallint tinyint)
② 内容长度固定,选取char类型使用 varchar()
③ 数据最好存储为整型的(时间、set/enum、ip地址)
索引是数据结构,其内部有算法(规律、规则)
四种:主键、惟一[例如用户名惟一]、普通、全文索引 ,复合索引
针对查询select语句起做用
sql语句在没有执行以前把全部须要的资源都准备好,咱们能够预先 查看下
咱们关心sql语句是否用到索引
explain sql语句\G;
① where
② 排序字段
select * from 表名 order by 字段 limit 1000000,50; 不会用索引
select * from 表名 order by 字段 limit 50; 用索引
select * from 表名 order by 字段 limit 100,50; 用索引
select * from 表名 order by 字段 limit 偏移量,50; 用索引
偏移量若是超过10万,就不会使用索引。
③ 索引覆盖
④ 连表查询,外键设置索引
① 字段独立
② 左原则(模糊查询)
③ 复合索引
④ or原则
① 被频繁使用的字段设置索引
字段被频繁用在where和order等条件里边。
数据表建立完毕,要预估那些字段被常用,就给其建立索引
② 执行时间长的sql语句考虑设计索引
能够利用"慢查询日志"收集这样的sql语句并优化设计索引
③ 逻辑很是重要的sql语句考虑设计索引
例如商城系统里边,会员给本身帐户充值就比较重要
还有会员下订单购物,进行付款的时候也比较重要。
④ 字段内容足够花样化,能够考虑设计索引
反面教材,性别不能设计索引(内容的取值很是少)
什么是前缀索引:
若是一个字段的内容的前边的n位信息已经足够能够标识当前的字段内容,就能够把字段的前n位得到出来并建立索引,
经过字段内容前n位建立的索引就称为"前缀索引"。
例如:
关伟
吕纪无
刘尚
王云斐
以上字段内容,经过前1位,就能够惟一标识当前字段内容,这样就把前1位取出来建立索引
好处:索引占据的物理空间要比较小,这样的索引运行速度快、效率高,对mysql总体性能提高有很大帮助。
具体操做:
alter table 表名 add key (字段(位数))
思考:
究竟是前几位能够标识当前字段内容
经过substring得到字段的前n为信息,从1开始递增时获取
获取的时候去除重复的,计算总个数,不断增长n的数值,直至总个数稳定
此时n的数值就是适合作"前缀索引"的数字。
索引是给sql语句作优化
前缀索引,是给索引作的优化
得到字段的前n位:substring(字段,开始位置,长度n) mysql函数
同上上图能够知道,经过前11位,能够给epassword字段设置索引。
什么是全文索引:
其余索引是把字段的内容做为一个总体进行索引设计
全文索引,相似咱们有一篇做文,把做文中的一些关键字给获取出来当成是索引内容。
具体理解,就是作like模糊查询,相似baidu搜索一些关键字效果。
全文索引注意:
① 字段类型必须为varchar/char/text类型
② mysql 5.6.4以前只有Myisam支持,5.6.4以后则Myisam和innodb都支持。
③ mysql中的全文索引目前只支持英文(不支持中文),若是须要支持中文可使用sphinx
④ 现实生产中mysql的全文索引不常用,sphinx常使用
mysql全文索引自做聪明,对关键字的收录有本身的考虑。
版本是5.5.27,所以只有Myisam支持全文索引。
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT
)engine=myisam charset utf8;
INSERT INTO articles (title,body) VALUES
('MySQL Tutorial','DBMS stands for DataBase ...'),
('How To Use MySQL Well','After you went through a ...'),
('Optimizing MySQL','In this tutorial we will show ...'),
('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
('MySQL vs. YourSQL','In the following database comparison ...'),
('MySQL Security','When configured properly, MySQL ...');
alter table articles add fulltext index `index_body` (body);
如今已经有了一个index_body的全文索引:
所以相似以下sql语句就可使用到索引了
select * from articles where body like '%内容%';
可是sql语句须要变形为:
select * from articles where match(字段body) against(内容);
alter table articles add fulltext index `index_fu` (title,body);
select * from articles where title like '%内容%' and body like '%内容%'
索引的数据结构
主要讨论两种:Myisam 和 Innodb
Mysql的数据结构都是B+tree结构
数据结构:数据以一种规律的、规则的方式组织在一个格式里边,能够保证咱们得到数据的快速性。
该Myisam索引结构称为"非聚合型"
上图说明,主键内容在该索引里边经过算法开始被查询、得到,并借助"指针"向下级寻找,直到找到对应的叶子节点。
叶子节点里边有该关键字对应的记录的物理地址,进而得到对应的记录信息。
索引运行原理:快速定位主键id值,得到对应记录物理地址,得到记录信息。
每一个主键id值都是一个节点,节点自己有指针。
最底层的节点称为"叶子节点",该节点与记录的物理地址直接联系
上图节点从上到下的层次数是索引结构的高度
每层节点的数目称为结构的宽度
结构的宽度、高度的数目由mysql底层算法计算得到(太高、过宽都不利于数据的快速获取)
Myisam其余索引结构与主键索引结构一致。
经过上图索引结构,咱们看到了 索引部分 和 数据部分是分离的,它们之间经过物理地址进行联系。
该Innodb索引结构称为"聚合型"
聚合在:"索引"和"数据"是合并在一个文件里边的。
下图表示innodb的其余索引(惟1、普通)
该(用户名字)其余索引运行原理:
① 经过索引结构内部的算法快速定位该名字对应的"叶子节点"
② 叶子节点 里边对应的是关键字的记录主键id值
③ 经过记录主键id值走主键索引便可
innodb(主键)索引运行原理:
① 经过索引结构快速定位主键id值对应的"叶子节点"
② 该叶子节点 里边直接与整条记录信息进行对应(而在Myisam里边,叶子节点与物理地址对应)
innodb索引:
普通索引关键字----->记录的主键id值------>记录的整条信息
有的被频繁执行的sql语句,比较消耗时间、消耗系统资源(没的优化可作)
而且每次得到数据还不太发生变化
那么就把这个sql语句得到信息给缓存起来,供后续执行使用
这样很是节省系统资源。
数据表的数据有变化 或者 数据表结构有变化,则缓存失效。
sql语句每次得到数据有变化。
例若有 时间信息、随机数等
生成缓存的sql语句对"空格"、"大小写"比较敏感
相同结果的sql语句,因为空格、大小写问题就会分别生成缓存。
sql_no_cache 不进行缓存
总结:
一个数据表里边存储的记录信息太多了,记录的条数达到1-2亿条信息。
这时该数据表的活性就大大下降,数据表的运行速度就比较慢、效率低下,影响mysql数据库的总体性能。
如今设置一个水平分割,把许多的记录信息分别存储到不一样的数据表里边,这样每一个表存储的记录就比较少,该表的活性大大提升。
分表设计的两种模式:
① 逻辑方式分表
mysql数据库自己就有分表技术,该方式的分表能够节省php的逻辑处理。
② 物理方式分表
本身手动建立多个数据表出来
php程序须要考虑分表算法:数据往哪一个表写,从哪一个表读
mysql自己就支持的分表技术
以上逻辑分表设计,在php程序里边无需设置额外算法代码,还像以往同样直接对goods数据表进行操做便可,mysql自己会考虑分表的算法。
具体为:key hash ---->[求余方式]
range list ---->[范围方式]
注意:分表字段必须是主键 或 主键的一部分
partition by key(条件字段id) partitions 10;
根据表达式/字段方式进行分表设计
partition by hash(表达式/字段) partitions 数量;
根据 字段/表达式 是否知足某个范围条件进行分表设计
partition by range(year(pubdate))(
partition hou70 values less than (1980),
partition hou80 values less than (1990),
partition hou90 values less than (2000),
partition hou00 values less than (2010)
)
根据 表达式/字段 的内容值是否在某个"列表"中进行分表设计。
partition by list(month(pubdate))(
partition spring values in (3,4,5),
partition summer values in (6,7,8),
partition autumn values in (9,10,11),
partition winter values in (12,1,2)
)
具体就是对已经存在的分表进行增长、减小操做。
增长分表 不会引发数据丢失。
减小分表 在range/list领域会形成数据丢失
在key/hash领域不会形成数据丢失,
这两个领域在进行减小分表的同时就把所有数据从新整合到存在的表中,
key/hash两种分表与业务逻辑关联不紧密。
求余方式: key/hash
> alter table 表名 add partitions 数量;
范围方式: range/list
> alter table 表名 add partition(
partition 名称 values less than (常量)
或
partition 名称 in (n,n,n)
);
求余方式(key/hash):
>alter table 表名 coalesce partition 12;
删除分表不会形成数据丢失,每次分表数据都从新整合到存在的分表里边。
范围方式(range/list):
>alter table 表名 drop partition 分区名称;
删除分表会形成数据丢失
给range分表写4条记录:
把"hou80"的分区删除,从下图查询结果看对应分表的数据也丢失了。
以上goods的物理分表须要增长php的算法逻辑:
须要计算记录从哪一个表读、给哪一个表写。
水平分表:是把一个表的所有记录信息分别存储到不一样的分表之中。
垂直分表:是把一个表的所有字段分别存储到不一样的表里边。
有的时候,一个数据表设计好了,里边有许多字段,可是这些字段有的是常用的,有的是不经常使用的。
例如,一个数据表有20个字段,其中10个字段是经常使用的,后10个字段是不经常使用的
那么在操做经常使用字段的时候,就不得不给其余不经常使用的字段也分配必定的资源进行操做。
数据表:
会员表: user_id 登陆名 密码 邮箱 手机号码 身高 体重 性别 家庭地址 身份证号码
以上表,红色是经常使用的,蓝色的是不经常使用的
为了使得经常使用字段运行速度更快、效率更高,把经常使用字段给挑选出来,所以数据表作如下设计:
会员表(主)字段:user_id 登陆名 密码 邮箱 手机号码
会员表(辅)字段:user_id 身高 体重 性别 家庭地址 身份证号码
以上把会员表根据字段是否经常使用给分为两个表的过程就是垂直分表。
架构设计也称为集群设计:由多台mysql服务器共同支撑网站的运行,每台服务器分担的工做就比较少,运行速度快、效率高。
mysql数据库在运行的时候通常查询/写入的sql语句比例为:7/1
而且查询消耗的资源比写入要更多。
所以能够设计一个"主从模式"的集群,与以前redis的主从模式使用模式一致。
维护备份的集群架构:
主从模式的集群架构:
咱们要把系统里边一些执行速度很是慢的sql语句给收集起来,并作分析优化,使得其执行速度加快。
总结:
分的是数据记录
求余:key/hash 范围:range/list
建立/增长分表:新建表时、分表建立完毕还能够增长
删除分表:key/hash不会形成数据丢失
range/list能形成数据丢失
php代码须要增长算法逻辑
分的是表的字段
架构集群有两种方式:
① 互为备份
② 主从模式[经常使用]