第四章:Schema与数据类型优化

1. 选择优化的数据类型

选择数据类型的原则

  • 更小的通常更好:选择可以正确存储数据的最小数据类型

    • 小的数据类型消耗更少的内存、CPU;占用更少的磁盘
  • 选用简单的数据类型:简单的数据类型通常需要更少的CPU周期来处理
    • 使用MySQL内建的类型来存储时间和日期
    • 使用整型存储IP地址
  • 尽量避免null值:通常情況下使用not null,除非真的需要存出null值
    • null值使得索引、索引統計、值比較都变得复杂
    • 可为null的列需要更多的空间来存储
    • InnoBD使用单独的bit来存储null值

数字分为:整数实数

1.1 整数类型

整数可以用:TINYINT、SMALLINT、INT、BIGINT类型来存储,分别占用8、16、24、32、64位的存储空间. 使用UNSIGNED属性标识整数,表示不可为负:

  • TINYINT.UNSIGNED可以存储的范围是0-255,而TINYINT的范围是-128~127

MySQL可以为整数类型指定宽度,例如INT(11),对于大多数应用是没有意义的,他不会限制值的合法范围,只是规定了MySQL的客户端来显示字符的个数,对于存储来说INT(11)和INT(20)占用的空间是相同的.

1.2 实数类型

实数是带有小数部分的数字,实数类型也不一定是用来存小数,可以用decimal来存储比bigint还大的整数.

MySQL既支持精确类型也支持不精确类型:

  • float和double类型支持使用标准的浮点运算进行近似计算.float占用4个字节,double占用8个字节,MySQL使用double进行内部的浮点数计算,
  • decimal用于存储精确的小数,支持精确计算;此外,CPU不支持decimal运算,因此MySQL服务层实现了decimal的精确计算,相对而言,CPU直接计算浮点数,因此更快.decimal占用的空间要比double多.

许多方法可以指定浮点列的精度,这样MySQL会悄悄使用不同的数据类型,或者在存储时进行取舍,因此建议只指定数据类型而不指定精度.鉴于空间和计算开销,应该只在对小数进行计算的场景下才使用decimal.

1.3 字符串类型

  • MySQL支持多种字符串类型,每种类型还有很多变种.
  • varchar和char是两种主要的字符串数据类型,这两种数据类型的存储方式和存储引擎有关.
1.3.1 varchar
  • varchar用于存储可边长的字符串,它仅使用需要的空间来存储数据-->节省空间
  • varchar使用额外的1个或者2个字节来存储数据长度
  • 节省了空间也带来了性能提升,但是执行update时可能会使时间变长
  • 适合用varchar存储的场景:
    • 字符串列的最大长度比平均长度大的多
    • 列的更新很少
    • 使用了复杂字符集(UTF-8)
1.3.2 char
  • char是定长的,MySQL根据定义的字符串长度分配固定的空间
  • char类型会根据需要使用空格填充以方便比较,较varchar而言不容易产生碎片
  • char适合存储短的或者长度接近一个固定值的串
    • 存储密码的MD5值
    • 存储二进制数据并需要比较时,char会更快
  • 对于任意存储引擎,填充和截取空格的结果都是一样的,因为是在服务层实现的
1.3.3 blob和text类型
  • blob和text是MySQL为很长的字符串设计的类型,分别采用二进制和字符串来存储.
  • 数据过长是,这两个类型在Innodb引擎中使用外部区域来存储,在行内使用1-4字节的指针指向这个外部区域.
1.3.4 使用枚举类型代替字符串
  • MySQL在存储枚举时非常紧凑,会根据列表值将的数量压缩到一个或两个字节大小,MySQL在映射关系"查找表"中保存"数字-字符串"的关系.
mysql>create table enum_test(
    e ENUM('fish','apple','dog')not null
);
mysql> insert into enum_test(e)values('fish','dog','apple');

这三行数据实际上存储为整数:

mysql> select e+0 from enum_test;

+---+
|e+0|
+---+
|  1|
|  3|
|  2|
+---+
  • 使用美剧不好的地方在与字符串列表时固定的,需要修改时必须将表删了重建.
  • 某些情况下,char/varchar和枚举列关联会导致性能下降.

1.4 日期和时间类型

MySQL能存储的最小时间单位是秒,但是也可以使用微秒级别的粒度进行临时运算.

1.4.1 DATETIME
  • 保存大范围的值,从1001年到9999年,精度位秒.
  • 格式:YYYYMMDDHHMMSS,8个字节存储
1.4.2 TIMESTAMP
  • 和UNIX时间戳一样保存了1970年1月1日午夜以来的秒数.
  • 占用4个字节的空间,只能保存1970-2038年
  • 显示的值依赖时区
  • 默认值为null,插入时没有指定默认值使用当前时间为这列的值

此外,可以用bigint来保存更小粒度的时间值

1.5 位数据类型

? MySQL之后少数的类型使用位来存储数据,例如bit和set而不管底层储存格式和方式如何,从技术上来说都是字符串.

1.6 选择标识符

标识列可能被用来与其他列比较,或者通过标识列寻找其他列,标识列也可能被用在外键.

在满足值的范围,并且保证未来的增长空间时应选择最小的 数据类型来作为标识列的类型:

  • 整数类型通常是比较好的类型,可以使用auto_increament.
  • 一般情形下,不建议使用枚举和set,这两者只适合存储固定的信息
  • 避免使用字符串,因为比较消耗空间并且比较时较整数类型慢

2.MySQL在schema中设计中的陷阱

  • 太多的列

    • MySQL的存储引擎API工作时需要在服务层和存储引擎层之间通过行缓冲格式拷贝数据,然后在服务层将缓冲内容解码成各个列,解码的过程时异常消耗性能的.
  • 太多的关联
    • 在MySQL下不能很好的使"实体-属性-值"(EAV)的设计模式工作.
    • MySQL限制了每个关联操作最多61张表,但EAV数据库需要很多自关联.
    • 一些经验表明,12个表以内的关联MySQL工作效率最高.
  • 全能的枚举
    • 防止过度使用枚举,因为枚举的天然不支持修改,一旦要修改代价会很高.
  • 变相的枚举
    • 集合set列允许一个或者多个值,这时候容易混乱:

      create table ...(is_default set('Y','N') not null default'N');

      如果这里真假两种情况不会同时出现,那么使用枚举会更加合适.

  • 非此此发明的null
    • 建议一般不要使用null值,即便真要用,可以使用0或者某些特定的值来代替,如空字符串.

3.范式和反范式

在范式化的数据库中所有数据出现且仅出现一次,而反范式的数据中,每个事实数据可能会出现多次,信息冗余.

3.1 范式的优点和缺点

写密集型的表按照范式规范设计性能会更好!

  • 范式化的更新更快
  • 数据较好的范式化时,很少的数据会冗余,也就是说只需要更新很少的数据
  • 范式化的数据很少冗余,占用的空间少,就可以更好更快的放在内存操作
  • 冗余较少时distinct和group by使用频率就会下降

3.2反范式的优点和缺点

  • 反范式的数据都在一张表中,可以很好的避免关联.
  • 如果不需要关联,则针对大部分查询慢(即使没有索引)需要全表扫描,那么当数据比内存大时全表扫描可能要比关联快很多.

3.3 混用范式和反范式

  • 最常见的反范式化设计是复制或者缓存,在不同的表中存储相同的某个列.
  • MySQL5.0之后可以用触发器更新缓存.

4.缓存表和汇总表

有时候提升性能最好的方法是在表中保存一写衍生的冗余的数据,但在某些时候,也需要创建一张完全的汇总表或者缓存表.

  • 缓存表:可以比较简单的从schema中其他表中获取(每次获取速度表较慢)数据的表(逻辑上冗余的表)
  • 汇总表:保存的是使用group by语句聚合数据的表(不是逻辑上冗余的数据).

5.总结

  • 尽量避免过度设计
  • 使用小和简单的合适数据类型,尽量避免使用null值
  • 尽量使用相同的数据类型存储相似或者相关的列,尤其是关联条件中的列
  • 注意可变长字符串
  • 尽量使用整型定义标识列
  • 避免使用MySQL已经遗弃的特性
  • 小心的使用枚举和set,最好避免使用bit
  • 范式是好的,但是很多时候反范式也是有必要的,这回带来好处

原文地址:https://www.cnblogs.com/mydailycoding/p/12348326.html

时间: 2024-10-10 18:16:28

第四章:Schema与数据类型优化的相关文章

高性能MySQL(四)—Schema与数据类型优化(1)

Schema与数据类型优化 选择优化的数据类型 下面是一些简单的原则: 更小的通常更好 一般情况下,应该尽量使用可以正确存储的最小数据类型.如:只需要存储0-200, tinyint unsigned就比较好.小的数据类型占的磁盘.内存和CPU缓存都较少,并且处理时需要的CPU周期数也更少. 简单就好 简单数据类型额操作通常需要更少的CPU周期.如:应该使用MySQL的內建类型来存储时间和日期而不是字符串.如:应该用整型存储IP地址. 尽量避免null 通常情况下最好指定列为NOT NULL,除

高性能MySQL笔记 第4章 Schema与数据类型优化

4.1 选择优化的数据类型   通用原则 更小的通常更好 前提是要确保没有低估需要存储的值范围:因为它占用更少的磁盘.内存.CPU缓存,并且处理时需要的CPU周期也更少. 简单就好 简单数据类型的操作需要更少的CPU周期. 尽量避免NULL 值可为NULL的列使得索引.索引统计和值比较都更复杂化.可为NULL的列会使用更多的存储空间. 整数类型 TINYINT SMALLINT MEDIUMINT INT BIGINT.分别使用8,16,24,32,64位存储空间.他们可以存储的值的范围从 -2

第四章-shceme和数据类型优化

选择数据类型的原则: 1.更小通常更好.因为占用更少磁盘,内存和cpu缓存.但是要确保没有低估,因为进行alter时,是很耗时和头疼的操作.所以当无法确定数据类型的时候,选择不会超过范围的最小类型. 2.简单就好.简单的数据类型消耗的cpu更好,比如整型比字符串好 3.尽量避免使用null.主要是因为mysql的内部实现问题,但这种优化一般效益比较小. Decimal 的缺点: 1.占用内存多 2.计算消耗的cpu多 所以不到必须情况最好不要使用.一种优化方法是对decimal乘以一定的量级,然

第04章 Schema与数据类型优化

反范式的设计可以加快某些类型的查询,但也可能是的另一些类型的查询变慢.添加计数表和汇总表是一种很好的优化查询的方式. 1 选择合适的数据类型 通常原则是: 更小的通常更好:一般情况下应该尽量使用可以正确存储数据的最小数据类型.更小的数据类型通常更快,因为他们占用很少的磁盘,内存和cpu缓存,在处理的时候需要的cpu周期也更少. 简单就好:简单数据类型的操作通常用更少的cpu周期.比如整数比字符操作代价低,因为字符集和校对规则使得字符比整形更复杂.比如,mysql使用內建类型来存储时间和日期,而不

高性能mysql 第4章 Schema与数据类型优化

基本原则: 更小的通常更好:占用更少的磁盘 内存和cpu缓存. 简单就好:比如整形比字符型代价更低.使用日期型来存储日期而不是字符串.使用整形存储ip地址. 尽量避免null:如果可以 加上not null约束.因为可以null的列使索引,索引统计,值比较都变得复杂.通常把可为null的列改为not null带来的性能提升比较小,调优时没有必要首先修正这种情况来排查问题.但是如果计划在列上建立索引,如果可以保证是not null,那么尽量加上. 整数类型: tinyint,smallint.,m

【MySQL】《高性能MySQL》学习笔记,第四章,Schema与数据类型优化

[MySQL]<高性能MySQL>学习笔记,第四章,Schema与数据类型优化 良好的逻辑设计和物理设计是高性能的基石,应该根据系统将要执行的查询语句来设计schema. 反范式的设计可以加快某些类型的查询,单同时可能使另一类型的查询变慢,比如添加计数表和汇总表是一种很好的优化查询的方式,但这些表的维护成本可能会很高. 1.选择优化的数据类型 更小的通常更好. ? 应该尽量使用可以正确存储数据的最小类型,更小的数据类型通常更快,因为他们占用更少的磁盘,内存和CPU缓存,并且处理时需要的CPU周

mysql笔记01 Schema与数据类型优化

Schema与数据类型优化 1. 选择优化的数据类型 1). 更小的通常更好:更小的数据类型通常更快,因为他们占用更少的磁盘.内存和CPU缓存,并且处理需要的CPU周期也更少. 2). 简单就好:简单的数据类型的操作通常需要更少的CPU周期.例如:整型比字符串操作的代价更低,因为字符集和校对规则(排序规则)是字符串比较比整型比较更复杂.这里有两个例子: 一个是应该使用MySQL内建的类型而不是字符串来存储日期和时间,另外一个是应该使用整型存储IP地址. 3). 避免使用null:通常情况下最好指

Schema与数据类型优化

Schema与数据类型优化 1.选择优化的数据类型 应该尽量使用可以存储数据的更小的数据类型.更小的数据类型通常更快,占用更少的磁盘.内存.缓存. 2.简单最好 整型比字符型要好,两个例子,应该使用Mysql内建的类型来存储日期而不是字符串:使用整形存储Ip地址.因为字符的校对.排序规则要复杂. 3.尽量避免使用Null. 因为可为Null的列使得索引和索引统计和值的比较变得复杂. 4.整数类型 整数类型分为:tinyint.smallint.mediumint.int.bigint.Mysql

mysql的schema与数据类型优化分析

Schema与数据类型优化: 1.选择优化的数据类型 更小的通常更好:一般情况下,尽量使用可以正确存储数据的最小数据类型 如:只需存0-200,tinyint unsigned更好. 简单就好:如:整型比字符串操作代价更低,应该使用mysql内建类型而不是字符串来存储日期和时间. 尽量避免NULL:通常情况下最好指定列为NOT NULL,除非真的要存储NULL值.如:查询中包含可为NULL的列对mysql来说更难优化. 2. 选择类型范围 如DATETIME和TIMESTAMP列都可以存储相同类