
麦子学院 2017-07-31 16:51
如何设计出高性能的mysql数据库?
回复:0 查看:2695
良好的逻辑设计和物理设计是高性能的基石,
应该根据系统将要执行的查询语句来设计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
,强制生成硬盘临时表浪费更多空间。
来源:伯乐在线