优化①:建立规范化表,消除数据冗余java
数据库范式是确保数据库结构合理,知足各类查询须要、避免数据库操做异常的数据库设计方式。知足范式要求的表,称为规范化表,范式产生于20世纪70年代初,通常表设计知足前三范式就能够,在这里简单介绍一下前三范式。数据库
通俗的给你们解释一下(可能不是最科学、最准确的理解)数据库设计
第一范式:属性(字段)的原子性约束,要求属性具备原子性,不可再分割;工具
第二范式:记录的唯一性约束,要求记录有唯一标识,每条记录须要有一个属性来作为实体的惟一标识。性能
第三范式:属性(字段)冗余性的约束,即任何字段不能由其余字段派生出来,在通俗点就是:主键没有直接关系的数据列必须消除(消除的办法就是再建立一个表来存放他们,固然外键除外)优化
固然,其实咱们常常打破第三范式。。。且不可避免的,其实就是要在数据冗余和处理速度之间找到合适的平衡点 。设计
优化②:合适的字段属性blog
先举个例子:索引
之前我作过的电商项目中,关于资金流水类型的字段的选取。原本资金流水类型总共就那么十几种,基本固定死的,那咱们就能够选择tinyint(4)就彻底足够了,对应的是java的byte。 (要知道的是,tinyint的长度就是8位,tinyint(1)和tinyint(4)只是显示长度)字符串
下面如下给出几个字段的建议:
0)数值型字段的比较比字符串的比较效率高得多,因此字段类型尽可能使用最小、最简单的数据类型。如IP地址可使用int类型,如我上面的例子。
1)建议不要使用DOUBLE,不只仅只是存储长度的问题,同时还会存在精确性的问题。
2)对于整数的存储,在数据量较大的状况下,建议区分开 TINYINT / INT / BIGINT 的选择(固然,那已是很老的事情了,如今其实不差这点性能)
3)char是固定长度,因此它的处理速度比varchar快得多,但缺点是浪费存储空间,不能在行尾保存空格。在MySQL中,MyISAM建议使用固定长度代替可变长度列;InnoDB建议使用varchar类型,由于在InnoDB中,内部行存储格式没有区分固定长度和可变长度。
4) 尽可能不要容许NULL,除非必要,能够用NOT NULL+DEFAULT代替。
5)text与blob区别:blob保存二进制数据;text保存字符数据,有字符集。text和blob不能有默认值。
实际场景:text与blob主要区别是text用来保存字符数据(如文章,日记等),blob用来保存二进制数据(如照片等)。blob与text在执行了大量删除操做时候,有性能问题(产生大量的“空洞“),为提升性能建议按期optimize table 对这类表进行碎片整理。
6) 自增字段要慎用,不利于数据迁移
7)强烈反对在数据库中存放 LOB 类型数据,虽然数据库提供了这样的功能,但这不是他所擅长的,咱们更应该让合适的工具作他擅长的事情,才能将其发挥到极致。(反正我么碰到过LOB类型数据)
8)尽可能将表字段定义为NOT NULL约束,这时因为在MySQL中含有空值的列很难进行查询优化,NULL值会使索引以及索引的统计信息变得很复杂,可使用0或者空字符串来代替。
9)尽可能使用TIMESTAMP类型,由于其存储空间只须要 DATETIME 类型的一半,且日期类型中只有它可以和实际时区相对应。对于只须要精确到某一天的数据类型,建议使用DATE类型,由于他的存储空间只须要3个字节,比TIMESTAMP还少。
优化③:索引
索引是一个表优化的重要指标,在表优化中占有极其重要的成分,因此上篇索引优化详解没看过的能够先看看,这里再也不赘叙。
优化④:表的拆分(大表拆小表)
一、垂直拆分(其实就是列的拆分将原来的一个有不少列的表拆分红多张表)
注意:垂直拆分应该在数据表设计之初就执行的步骤,而后查询的时候用jion关键起来便可;
一般咱们按如下原则进行垂直拆分:
缺点也很明显,须要使用冗余字段,并且须要join操做。
二、水平拆分( 若是你发现某个表的记录太多,例如超过一千万条,则要对该表进行水平分割。水平分割的作法是,以该表主键的某个值为界线,将该表的记录水平分割为两个表。)
固然,咱们还能够用增量法。如流水这类不会改变的数据,咱们用增量查询。
1.建立一张日充值表,记录天天充值总额
2.天天用定时器对当前充值记录进行结算
3.建立每个月充值表,每个月最后一天用定时器计算总额
4.则要查询总额,则从月报表中汇总,再从日报表查询当天以前的数据汇总,再加上今天的使用当天流水表记录今天的流水,三张表加起来,汇总。这样子效率是极好的!
优化⑤:传说中的‘三少原则’
①:数据库的表越少越好
②:表的字段越少越好
③:字段中的组合主键、组合索引越少越好
固然这里的少是相对的,是减小数据冗余的重要设计理念。