MySQL 学习之高性能表设计规范详解

良好的逻辑设计和物理设计是高性能的基石,  应该根据系统将要执行的查询语句来设计schema,  这往往需要权衡各种因素。本文和大家分享的就是MySQL  高性能表设计的一些 规范,一起来看看吧,希望对大家  学习mysql有所帮助。
    一、选择优化的数据类型
  MySQL 支持的数据类型非常多, 选择正确的数据类型对千获得高性能至关重要。
    更小的通常更好
  更小的数据类型通常更快,  因为它们占用更少的磁盘、  内存和CPU 缓存, 并且处理时需要的 CPU 周期也更少。
    简单就好
  简单数据类型的操作通常需要更少的CPU 周期。 例如, 整型比字符操作代价更低, 因为字符集和校对规则(排序规则 )使字符比较比整型比较更复杂。
    尽量避免NULL
  如果查询中包含可为NULL  的列, 对 MySQL 来说更难优化, 因为可为 NULL  的列 使得索引、 索引统计和值比较都更复杂。 可为  N ULL 的列会使用更多的存储空间, 在 MySQL 里也需要特殊处理。 当可为NULL 的列被索引时, 每个索引记录需要一个额 外的字节, 在 MyISAM  里甚至还可能导致固定大小的索引(例如只有一个整数列的索引)变成可变大小的索引。
  当然也有例外,  例如值得一提的是, lnnoDB  使用单独的位  (bit)  存储 NULL  值, 所以对于稀疏数据注  4  有很好的空间效率。
    1.整数类型
  有两种类型的数字:整数 (whole number)  和实数  (real number)  。 如果存储整数, 可以使用这几种整数类型: TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT 。分别使用 8,16, 24, 32, 64 位存储空间。
  整数类型有可选的   UNSIGNED  属性,表示不允许负值,这大致可以使正数的上限提高一倍。  例如 TINYINT. UNSIGNED  可以存储的范围是  0 – 255,  而  TINYINT  的存储范围是  -128 -127  。
    有符号和无符号类型使用相同的存储空间,并具有相同的性能  ,  因此可以根据实际情况选择合适的类型。
  你的选择决定 MySQL  是怎么在内存和磁盘中保存数据的。 然而, 整数计算一般使用 64  位的  BIGINT 整数, 即使在  32  位环境也是如此。( 一些聚合函数是例外, 它们使用 DECIMAL  或  DOUBLE  进行计算)。
  MySQL  可以为整数类型指定宽度, 例如  INT(11),  对大多数应用这是没有意义的:它不会限制值的合法范围,只是规定了 MySQL  的一些交互工具(例如  MySQL  命令行客户端)用来显示字符的个数。 对千存储和计算来说,  INT(1)  和  INT(20)  是相同的。
    2.实数类型
  实数是带有小数部分的数字。  然而,  它们不只是为了存储小数部分,也可以使用DECIMAL  存储比 BIGINT  还大的整数。
  FLOAT 和 DOUBLE 类型支持使用标准的浮点运算进行近似计算。
  DECIMAL 类型用于存储精确的小数。
  浮点和DECIMAL 类型都可以指定精度。 对千 DECIMAL 列, 可以指定小数点前后所允许的 最大位数。这会影响列的空间消耗。
  有多种方法可以指定浮点列所需要的精度,  这会使得MySQL 悄悄选择不同的数据类型,或者在存储时对值进行取舍。 这些精度定义是非标准的,   所以我们建议只指定数据类型,不指定精度。
    浮点类型在存储同样范围的值时, 通常比DECIMAL使用更少的空间。FLOAT使用4个字节存储。DOUBLE占用8个字节,相比FLOAT有更高的精度和更大的范围。和整数类型一样, 能选择的只是存储类型; MySQL使用DOUBLE作为内部浮点计算的类型。
  因为需要额外的空间和计算开销,所以应该尽扯只在对小数进行精确计算时才使用DECIMAL 。   但在数据最比较大的时候, 可以考虑使用BIGINT代替DECIMAL, 将需要存储的货币单位根据小数的位数乘以 相应的倍数即可。
    3.字符串类型
    VARCHAR
  用于存储可变⻓字符串,长度支持到65535
  需要使用1 或 2 个额外字节记录字符串的长度
  适合:字符串的最大⻓度比平均⻓度⼤很多;更新很少
    CHAR
  定⻓,⻓度范围是1~255
  适合:存储很短的字符串,或者所有值接近同一个长度;经常变更
    慷慨是不明智的
  使用VARCHAR(5) 和 VARCHAR(200) 存储 ’hello’ 的空间开销是一样的。 那么使用更 短的列有什么优势吗?
  事实证明有很大的优势。  更长的列会消耗更多的内存,  因为MySQL 通常会分配固定大小的内存块来保存内部值。 尤其是使用内存临时表进行排序或操作时会特别糟糕。 在利用磁盘临时表进行排序时也同样糟糕。
  所以最好的策略是只分配真正需要的空间。
    4.BLOB和TEXT类型
  BLOB 和  TEXT 都是为存储很大的数据而设计的字符串数据类型, 分别采用 二进制和字符方式存储 。
  与其他类型不同, MySQL 把每个 BLOB 和 TEXT 值当作一个独立的对象处理。 存储引擎 在存储时通常会做特殊处理。 当 BLOB 和 TEXT 值太大时, InnoDB 会使用专门的  “ 外部 “ 存储区域来进行存储, 此时每个值在行内需要 1 – 4 个字节存储 存储区域存储实际的值。
  BLOB  和  TEXT  之间仅有的不同是  BLOB  类型存储的是二进制数据, 没有排序规则或字符集, 而 TEXT 类型有字符集和排序规则
    5.日期和时间类型
  大部分时间类型  都没有替代品,  因此没有什么是最佳选择的问题。  唯一的问题是保存日期和时间的时候需要做什么。 MySQL 提供两种相似的日期类型:  DATE TIME 和  TIMESTAMP 。
  但是目前我们更建议存储时间戳的方式,因此该处不再对 DATE TIME 和  TIMESTAMP 做过多说明。
    5.其他类型
    5.1选择标识符
  在可以满足值的范围的需求,  井且预留未来增长空间的前提下,  应该选择最小的数据类型。
    整数类型
  整数通常是标识列最好的选择,  因为它们很快并且可以使用AUTO_INCREMENT 。
    ENUM和SET类型
  对于标识列来说,EMUM 和 SET 类型通常是一个糟糕的选择, 尽管对某些只包含固定状态或者类型的静态  ” 定义表 ”  来说可能是没有问题的。 ENUM 和 SET 列适合存储固定信息, 例如有序的状态、 产品类型、 人的性别。
    字符串类型
  如果可能,  应该避免使用字符串类型作为标识列,  因为它们很消耗空间,  并且通常比数字类型慢。
  对千完全 “ 随机 ”  的字符串也需要多加注意, 例如  MDS()  、  SHAl()  或者  UUID()  产生的字符串。 这些函数生成的新值会任意分布在很大的空间内, 这会导致  INSERT  以及一些 SELECT 语句变得很慢。如果存储  UUID  值, 则应该移除  “-“ 符号。
    5.2特殊类型数据
  某些类型的数据井不直接与内置类型一致。  低千秒级精度的时间戳就是一个例子,另一个例子是以个1Pv4 地址,人们经常使用 VARCHAR(15) 列来存储 IP 地址,然而, 它们实际上是 32 位无符号整数, 不是字符串。用小数点将地址分成四段的表示方法只是为了让人们阅读容易。所以应该用无符号整数存储 IP 地址。 MySQL 提供 INET_ATON() 和 INET_NTOA() 函数在这两种表示方法之间转换。
    二、表结构设计
    1.范式和反范式
  对千任何给定的数据通常都有很多种表示方法,  从完全的范式化到完全的反范式化,  以及两者的折中。  在范式化的数据库中,  每个事实数据会出现并且只出现一次。  相反,  在反范式化的数据库中,  信息是冗余的,  可能会存储在多个地方。
    范式的优点和缺点
  为性能提升考虑时,经常会被建议对 schema  进行范式化设计,尤其是写密集的场景。
  ·  范式化的更新操作通常比反范式化要快。
  ·  当数据较好地范式化时,就只有很少或者没有重复数据,所以只需要修改更少的数据。
  ·  范式化的表通常更小,可以更好地放在内存里,所以执行操作会更快。
  ·  很少有多余的数据意味着检索列表数据时更少需要  DISTINCT  或者  GROUP BY 语句。
    反范式的优点和缺点
  不需要关联表,则对大部分查询最差的情况—— 即使表没有使用索引 —— 是全表扫描。 当数据比内存大时这可能比关联要快得多,因为这样避免了随机 I/0 。
  单独的表也能使用更有效的索引策略。
    混用范式化和反范式化
  在实际应用中经常需要混用,可能使用部分范式化的 schema  、 缓存表,以及其他技巧。
  表适当增加冗余字段,如性能优先,但会增加复杂度。可避免表关联查询。
    简单熟悉数据库范式
第一范式(1NF) :字段值具有原子性 , 不能再分 ( 所有关系型数据库系统都满足第一范式 );
  例如:姓名字段, 其中姓和名是一个整体 , 如果区分姓和名那么必须设立两个独立字段 ;
  第二范式(2NF) :一个表必须有主键 , 即每行数据都能被唯一的区分 ;
  备注:必须先满足第一范式;
  第三范式(3NF) :一个表中不能包涵其他相关表中非关键字段的信息 , 即数据表不能有沉余字段 ;
  备注:必须先满足第二范式;
    2.表字段少   
  · I/O 高效
  ·  字段分开维护简单
  ·  单表 1G 体积  500W ⾏行评估
  ·  单⾏行不超过 200Byte
  ·  单表不超过 50 个 INT 字段
  ·  单表不超过 20 个 CHAR(10) 字段
  ·  建议单表字段数控制在 20 个以内
  ·  拆分 TEXT/BLOB , TEXT 类型处理性能远低于 VARCHAR ,强制生成硬盘临时表浪费更多空间。
来源:伯乐在线
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值