Schema与数据类型优化

一、Mysql支持的数据类型

数据类型 BIT 描述
TINYINT 8 整型,有符号范围-128~127,无符号范围0~255,
SMALLINT 16 整型,有符号范围-32768~32767,无符号范围0~65535,
MEDIUMINT 24 整型,有符号范围-8388608~8388607,无符号范围0~16777215,
INT 32 整型,有符号范围-2147483648~2147483647,无符号范围0~4294967295,
BIGINT 64 整型,有符号范围-2^63~2^63-1,无符号范围0~2^64-1,
FOLAT 32 浮点型,近似计算。表示形式 FLOAT(M,D)M代表总位数,D代表小数位数
DOUBLE 64 浮点型,近似计算。表示形式 DOUBLE(M,D)M代表总位数,D代表小数位数
DECIMAL 最大位数65位 浮点型,精确计算。表示形式 DECIMAL(M,D)M代表总位数,D代表小数位数
VARCHAR 最大(65,535+2)*8 字符串类型,可变长度,长度通过前缀一个或两个字节来维护,需要指定字符集和校对集默
CHAR 最大255*8 字符串类型,固定长度,创建表时确定,需要指定字符集和校对集,默认填充是空格
BINARY 最大255*8 二进制字符串类型,存储的是字节,默认填充是\0,其他跟CHAR相同
VARBINARY 最大(65,535+2)*8 二进制字符串类型,存储的是字节,其他跟VARCHAR相同
BLOB 2^M(BLOB类型的长度) BLOB值被视为二进制字符串(字节字符串)。它们有二进制字符集和排序规则,比较和排序基于列值中字节的数值。
TEXT 2^M(TEXT类型的长度) 文本值被视为非二进制字符串(字符串)。它们具有二进制以外的字符集,并且根据字符集的排序规则对值进行排序和比较。
ENUM   枚举是一个字符串对象,其值从允许值列表中选择,这些允许值在创建表时在列规范中显式枚举。Mysql在存储枚举时非常紧凑,会根据列表值的数量压缩到一个或者两个字节中。Mysql在内部会将每个值在列表中的位置保存为整数,并且在表的.frm文件中保存”数字-字符串“映射关系的“查找表”。
SET 64个不同的成员

集合是一个字符串对象,可以有零个或多个值,每个值都必须从创建表时指定的允许值列表中选择。由多个集合成员组成的集合列值由逗号(,)分隔的成员指定。其结果是,设置的成员值本身不应包含逗号。Set在Mysql内部是以一系列打包的位的集合来表示的。

SET('a','b','c','d'):

SET Member Decimal Value Binary Value
'a' 1 0001
'b' 2 0010
'c' 4 0100
'd' 8 1000
DATETIME 8*8 DATETIME类型用于同时包含日期和时间部分的值。MySQL检索并显示“YYYY-MM-DD hh:MM:ss”格式的日期时间值。支持的范围是“1000-01-01 00:00:00”到“9999-12-31 23:59:59”。精度为秒,与时区无关。
TIMESTAMP 4*8 时间戳数据类型用于包含日期和时间部分的值。时间戳的范围是“1970-01-01 00:00:01”UTC到“2038-01-19 03:14:07”UTC。精度为秒,依赖于时区。
BIT[M] 64 位数据类型用于存储位值(0,1)。位(M)的一种类型允许存储M位值。M的范围从1到64。

二、范式

  • 第一范式:第一范式(1NF)要求数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值。若某一列有多个值,可以将该列单独拆分成一个实体,新实体和原实体间是一对多的关系。在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库。
  • 第二范式:满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式要求实体中每一行的所有非主属性都必须完全依赖于主键;即:非主属性必须完全依赖于主键。完全依赖:主键可能由多个属性构成,完全依赖要求不允许存在非主属性依赖于主键中的某一部分属性。若存在哪个非主属性依赖于主键中的一部分属性,那么要将发生部分依赖的这一组属性单独新建一个实体,并且在旧实体中用外键与新实体关联,并且新实体与旧实体间是一对多的关系。
  • 第三范式:满足第三范式必须先满足第二范式。第三范式要求:实体中的属性不能是其他实体中的非主属性。因为这样会出现冗余。即:属性不依赖于其他非主属性。如果一个实体中出现其他实体的非主属性,可以将这两个实体用外键关联,而不是将另一张表的非主属性直接写在当前表中。

上述是数据库中对三种范式的定义,下面说一下我自己的看法:

  • 第一范式:目前Mysql中所建的表包含都符合第一范式,第一范式属于一种建立关系模型的规范,我们可以在一个列中包含多个值,只要我们愿意,但这样会存在一些潜在的问题,比如在发现冗余数据和建立数据关系等等会复杂很多,通过第一范式,不仅能够让关系模型更加简单,也为后续的优化做了铺垫,比如后面的范式。
  • 第二范式:第二范式中所有的非主属性全部依赖于主键,假如,其中某个属性依赖于某个非主属性或者对主键部分依赖(主键由AB构成,此时单独依赖于A或B构成部分依赖),那么根据第二范式,我们需要把表格拆开,这些不依赖于主键的用单独的关系模型表示。第二范式从理论上避免了部分依赖,解决了主属性与非主属性之间冗余的问题。
  • 第三范式:第二范式解决了非主属性部分依赖主键的问题,但没有解决非主属性依赖非主属性的问题,怎么理解呢,在非主属性中存在A B两个字段,A依赖于B,当然此时A也依赖于主键,但此时假如我们按照第一第二范式建立关系模型,完全可以通过B找到A,所以可以把这两个字段新建一个实体。

三、建立Schema

1、选择优化的数据类型

在选择数据类型时,应选择最简单的数据类型,通常整型要比浮点数和字符串简单(字符串需要字符集和校验规则),在选择数据类型大小时,应选择能够满足需求的最小数据类型,并且尽量避免NULL。

2、范式与反范式

在定义关系模型时,应当意识到Mysql是一个IO密集型的系统,Mysql的数据和操作都需要记录在磁盘文件中,尽管范式避免了数据的冗余,节约了计算时CPU的时间,但是应当避免建立过多的关联,对于写频繁的操作,分离出频繁部分的关系模型单独表,对与读操作频繁的操作,通过冗余提升查询效率。

四、建表规约
1. 【强制】表达是与否概念的字段,必须使用 is _ xxx 的方式命名,数据类型是 unsigned tinyint
( 1 表示是,0 表示否 ) 。
说明:任何字段如果为非负数,必须是 unsigned 。
正例:表达逻辑删除的字段名 is_deleted ,1 表示删除,0 表示未删除。
2. 【强制】表名、字段名必须使用小写字母或数字 , 禁止出现数字开头,禁止两个下划线中间只
出现数字。数据库字段名的修改代价很大,因为无法进行预发布,所以字段名称需要慎重考虑。
说明:MySQL 在 Windows 下不区分大小写,但在 Linux 下默认是区分大小写。因此,数据库
名、表名、字段名,都不允许出现任何大写字母,避免节外生枝。
正例: aliyun _ admin , rdc _ config , level 3_ name
反例: AliyunAdmin , rdcConfig , level _3_ name
3. 【强制】表名不使用复数名词。
说明:表名应该仅仅表示表里面的实体内容,不应该表示实体数量,对应于 DO 类名也是单数
形式,符合表达习惯。
4. 【强制】禁用保留字,如 desc 、 range 、 match 、 delayed 等,请参考 MySQL 官方保留字。
5. 【强制】主键索引名为 pk_ 字段名;唯一索引名为 uk _字段名 ; 普通索引名则为 idx _字段名。
说明: pk_ 即 primary key;uk _ 即 unique key;idx _ 即 index 的简称。
6. 【强制】小数类型为 decimal ,禁止使用 float 和 double 。
说明: float 和 double 在存储的时候,存在精度损失的问题,很可能在值的比较时,得到不
正确的结果。如果存储的数据范围超过 decimal 的范围,建议将数据拆成整数和小数分开存储。
7. 【强制】如果存储的字符串长度几乎相等,使用 char 定长字符串类型。
8. 【强制】 varchar 是可变长字符串,不预先分配存储空间,长度不要超过 5000,如果存储长
度大于此值,定义字段类型为 text ,独立出来一张表,用主键来对应,避免影响其它字段索
引效率。
9. 【强制】表必备三字段: id , gmt _ create , gmt _ modified 。
说明:其中 id 必为主键,类型为 unsigned bigint 、单表时自增、步长为 1。 gmt_create,
gmt_modified 的类型均为 date_time 类型,前者现在时表示主动创建,后者过去分词表示被
动更新。
10. 【推荐】表的命名最好是加上“业务名称_表的作用”。
正例: alipay _ task / force _ project / trade _ config
11. 【推荐】库名与应用名称尽量一致。
12. 【推荐】如果修改字段含义或对字段表示的状态追加时,需要及时更新字段注释。
13. 【推荐】字段允许适当冗余,以提高查询性能,但必须考虑数据一致。冗余字段应遵循:
1 ) 不是频繁修改的字段。
2 ) 不是 varchar 超长字段,更不能是 text 字段。
正例:商品类目名称使用频率高,字段长度短,名称基本一成不变,可在相关联的表中冗余存
储类目名称,避免关联查询。
14. 【推荐】单表行数超过 500 万行或者单表容量超过 2 GB ,才推荐进行分库分表。
说明:如果预计三年后的数据量根本达不到这个级别,请不要在创建表时就分库分表。
15. 【参考】合适的字符存储长度,不但节约数据库表空间、节约索引存储,更重要的是提升检
索速度。
正例:如下表,其中无符号值可以避免误存负数,且扩大了表示范围。

你可能感兴趣的:(mysql,mysql)