良好的逻辑设计和物理设计是高性能的基石,前期的表结构设计质量,会直接影响基于表结构的业务SQL性能,所以,表结构的设计质量,直接关系到系统的运行情况,甚至是系统的用户体验,本章,主要对MySQL支持的数据进行讲解,说明数据类型的优缺点及适用场景 一般情况下,应该尽量选择可以正确存储数据的最小数据类型,因为它们占用的磁盘、内存和CPU缓存更少,并且调用CPU周期也更短,但是如果由于前期选择的数据类型支持的范围不足以支持业务数据,需要修改数据类型以增加数据范围,这将需要一个非常耗时和痛苦的操作,所有在设计数据类型时,无法确认哪个数据类型是最好的,就选择你觉得不会超过范围的最小类型。 简单的数据类型的操作通常需要更少的CPU周期,例如整形比字符串代价更低、使用内建类型(datetime)而不是字符串来保持时间 null是MySQL数据列的默认属性,但是通常情况下,最好知道列为NOT NULL,除非系统真的需要保持NULL值,查询中包含NULL的列,对MySQL来说,更难优化,因为NULL会使得所有、索引统计更为复杂 在为列选择数据类型时,第一步需要确定合适的大致类型,下一步就是选择具体的类型,有些数据,有几种数据类型都支持存储,只是它们的存储范围、精度不一样,这就需要我们根据业务来选择更加合适的类型,下面将对MySQL支持的数据类型进行介绍 数据类型: 特性: tip:整数可以指定宽度,但是幷不能限制数据的范围,它只是规定了在交互工具上显式的字符个数,对于存储来说,INT(1)和INT(20)没有区别 数据类型: 特性: tip:可以通过对要存储的高精度小数据数据乘以相应的倍数后用bigint来进行存储,因为bigint开销更,当然,只有在数据量比较大的时候才需要考虑这样做。 数据类型: 特性: tip:1. 当使用VARCHAR 时,如果表使用ROW_FORMAT = FIXED,每一行都会使用定长存储,这回很浪费空间 数据类型: 特性: 数据类型: IPv4地址,可以使用无符号整数存储IP地址,MySQL提供inet_ATON()和INET_NTOA()来转化ip地址 MySQL的存储引擎API在工作时,需要在服务器层和存储引擎层之间进行缓冲格式拷贝数据,然后在服务器层将缓存内容解码成各个列,而转换的代价依赖列的数量。 大多的关联,会导致解析和优化查询的代价成为问题,单个查询,最好在12个表以内做关联 使用枚举,当需要在枚举列表中增加一个新的值时,需要做一次ALTER TABLE操作,这是全表的阻塞操作,操作起来会很麻烦 避免使用NULL会带来很多好处,而且即使需要存储null值,也可以考虑使用其他的特殊值来代替,但是也不能走极端,当使用其他替代方案会导致不确定性,或者bug时,也许null幷不是不能接受的,而且MySQL会在索引中存储null的值,只是处理起来相比于not null 更复杂一点 范式化设计的schema通常的缺点是需要关联,稍微复杂一点的语句在符合范式的schema上都可能需要至少一次关联 范式化和反范式化各有优缺点,在正常的情况下,我们应综合业务需要,混合使用二者,所谓,黑猫白猫,能抓老鼠的才是好猫。 有时,提升性能最好的办法是在同一张表中保存衍生的冗余数据,然而有时候也需要创建一张完全独立的汇总表和缓存表,汇总表,指的是对某些数据进行聚合而产生具有统计功能的表,缓存表用来存储那些可以比较简单获取但获取速度比较慢的数据。 汇总表 缓存表 许多数据库管理系统都提供了一个叫物化视图的功能,物化视图实际上是预先计算并且存储在磁盘上的表,可以通过各种各样的策略刷新和更新,MySQL并不支持物化视图,然而我们可以使用Jsitin swanhart的开源工具Flexviews,对比传统的维护汇总表和缓存表的方法,Flexviews通过提取对源表的更改,可以增量的重新计算物化视图的内容。 计数器表最大的问题就是会遇到更新并发的问题,当多个线程对计数字段进行更新时,因为互斥的关系,这些更新需要串行化的执行,这会严重影响性能,这里有个和好的技巧可供参开,而且这个思路也可以在其他地方获益 比如,你要记录一个网站的点击次数,你可能会建一张表 每点击一次,就执行如下sql: 但是当许多人点击时,这些事务只能串行的执行,这时,可以考虑如下修改: 这时,在进行更新时,就可以随机对一行数据进行更新 当要获得统计结果时,需要使用下面这样的聚合查询 更进一步,每隔一段时间开始一个新的计数器,可以做如下修改: 更新则可使用如下语句 MySQL的ALTER TABLE操作的性能对大表来说是个大问题,MySQL执行大部分修改表结构操作的方法是用新的结构创建一个空表,从旧表中查出素有数据插入新表,然后删除旧表,这样的操作可能需要花费很长的时间,如果内存不足而表又很大,而且需要很多索引的情况下尤其如此。 对于常见的场景,能使用的技巧有两种: 理论上,MYSQL可以跳过创建新表的步骤,列的默认值实际上存在表的.frm中,可以直接修改这个文件而不需要改动表本身,然而mysql还没有采取这种优化的方法,所以ALTER TABLE 操作都将导致表重建 这个语句会直接修改.frm而不涉及表数据 tip:ALTER TABLE 允许使用ALTER COLUMN 、MODIFY COLUMN 、CHANGE COLUMN 语句修改列 有时候mysql会在没有必要的时候重建表,如果愿意冒一点风险,可以让mysql做一些其他类型的修改而不用重建表。 良好的schema设计原则是普遍适用的,但是MySQL有他自己的实现细节要注意,概况来讲,尽可能保持任何东西小而简单总是好的。有以下简单的原则值得你去考虑使用一、选择数据类型的基本原则
1. 更小的通常最好
2. 简单就好
3. 尽量避免NULL
二、数据类型
1.整数类型
1.TINYINT 8位
2.SMALLINT16位
3.MEDIUMINT24位
4.INT32位
5.BIGINT64位
2.实数整形
1.FLOAT 和DOUBLE 支持使用标准的浮点运算进行近似计算
2. DECIMAL用于存储精确的小数。
1. FLOAT 和DOUBLE 在存储相同范围的值时,比DECIMAL使用空间更少
2. DOUBLE(8字节)比FLOAT(4字节)有更高的精度和更大的范围
3. DECIMAL支持对小数进行精确计算,但是需要额外的空间和计算开销,因为CPU不支持对DECIMAL的直接计算,需要MySQL内部自身的实现3.字符串类型
1.CHAR 用于存储固定长度的字符串类型
2. VARCHAR 用于存储不定长的字符串数据类型
3. TEXT用于存储很大的数据而设计的字符串类型
4.BINARY和CHAR 对应的二进制字符串
5. VABINARY 和VARCHAR 对应的二进制字符串
6.BLOB和TEXT对应的二进制字符串
9. VARCHAR (5)和VARCHAR (200)存储hello使用的空间开销是一样的,但是VARCHAR (200)会消耗更多的内存,因为MySQL会分配固定大小的内存来保持内部值,尤其是使用内存临时表进行操作时会很糟糕,所有尽量只分配真正需要的空间4.日期和时间类型
1.DATETIME 用于存储1001年到9999年的时间,精度为秒
2. TIMESTAMP用于存储1970年1月1日午夜以来的秒数
tip:TIMESTAMP最远只能表示到2038年的时间5.位数据类型
1.BIT用于在一个列存储多个true/false值
2. SET用于合并存储很多的truefalse6.特殊类型数据inte
三、MySQL schema设计中的陷阱
1.太多的列
2.太多的关联
3.全能的枚举
4.非此发明的NULL
三、范式和反范式
1.范式的优点和缺点
2.反范式的优点和缺点
四、缓存表和汇总表
使用汇总表,相比于实时进行汇总计算,高效了很多,因为实时计算总是需要扫描大部分的数据,或者索引要求很高,但是有一个问题就是汇总表总是在使用前就多某一段的数据进行了汇总,导致实时性不高,但有时候也有一个折中的办法,就是一段时间的数据使用汇总表,而当前一小段的数据使用实时数据进行计算。
有时,我们需要很多不同的的索引组合来加速各种类型的查询,这些矛盾的需求有时需要创建一张只包含主表中部分列的缓存表1.物化视图
2.计数器表
create table hit_count(cnt int unsigned not null) engine = innoDB;
update hit_count set cnt -= cnt+1;
create table hit_count( slot tinyint unsigned not null primary key, cnt int unsigned not null ) engine = innoDB;
update hit_count set cnt = cnt+1 where slot = RAND()*100;
select sum(cnt) from hit_counter;
create table daily_hit_counter( day date not null, slot tinyint unsigned not null, cnt int unsigned not null, primary key(day, slot) )engine=InnoDB;
insert into daily_hit_counter(dat, slot, cnt) values (current_date, rand()*100,1) on duplicate key update cnt = cnt+1;
五、加快ALTER TABLE 操作的速度
一、先在一台不提供服务的机器上执行ALTER TABLE 操作,然后和提供服务的主库进行切换。
二、使用影子拷贝,创建一张和源表结构一样的新表,然后通过重命名的和删表操作交换两张表
另外一种方法是通过ALTER COLUMN操作来改变列的默认值:ALTER TABLE sakila.film ALTER COLUMN rental_duration SET DEFAULT 5
只修改.frm文件
快速创建索引
总结
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算