MySQL 数据库设计规范( 二 )

  • 【强制】避免使用与表名相同的字段名,这会在编写查询时造成混淆 。
  • 【强制】在数据库模式上定义外键 。
  • 【强制】避免使用缩写或基于首字母缩写词的名称 。
  • 【强制】外键列必须具有表名及其主键,例如:blog_id 表示来自表博客的外键 id 。
  • 字段数据类型优化
    1. 【建议】表中的自增列(auto_increment 属性),推荐使用 bigint 类型 。因为无符号 int 存储范围为 0~4,294,967,295(不到 43 亿),溢出后会导致报错 。
    2. 【建议】业务中选择性很少的状态 status、类型 type 等字段推荐使用 tinytint 或者 smallint 类型节省存储空间 。
    3. 【建议】业务中 IP 地址字段推荐使用 int 类型,不推荐用 char(15) 。因为 int 只占 4 字节,可以用如下函数相互转换,而 char(15) 占用至少 15 字节 。
    select inet_aton('192.168.2.12');select inet_ntoa(3232236044);
    JAVA 保存字符串ip 转 int 类型
    public static long ipToLong(String addr){String[] addrArray = addr.split("\.");long num = 0;for (int i = 0; i < addrArray.length; i++){int power = 3 - i;num += ((Integer.parseInt(addrArray[i]) % 256 * Math.pow(256, power)));}return num;}public static String longToIp(long i){return ((i >> 24) & 0xFF) + "." +((i >> 16) & 0xFF) + "." +((i >> 8) & 0xFF) + "." +(i & 0xFF);}4.【建议】不推荐使用 enum,set 。因为它们浪费空间,且枚举值写死了,变更不方便 。推荐使用 tinyint 或 smallint 。
    【MySQL 数据库设计规范】5.【建议】不推荐使用 blob,text 等类型 。它们都比较浪费硬盘和内存空间 。在加载表数据时,会读取大字段到内存里从而浪费内存空间,影响系统性能 。建议和 PM、RD 沟通,是否真的需要这么大字段 。InnoDB 中当一行记录超过 8098 字节时,会将该记录中选取最长的一个字段将其 768 字节放在原始 page 里,该字段余下内容放在 overflow-page 里 。不幸的是在 compact 行格式下,原始 page 和 overflow-page 都会加载 。
    6.【建议】存储金钱的字段,建议用 int 以分为单位存储,最大数值约 4290 万,程序端乘以 100 和除以 100 进行存取 。因为 int 占用 4 字节,而 double 占用 8 字节,空间浪费 。
    7.【建议】文本数据尽量用 varchar 存储 。因为 varchar 是变长存储,比 char 更省空间 。MySQL server 层规定一行所有文本最多存 65535 字节,因此在 utf8 字符集下最多存 21844 个字符,超过会自动转换为 mediumtext 字段 。而 text 在 utf8 字符集下最多存 21844 个字符,mediumtext 最多存 2^24/3 个字符,longtext 最多存 2^32 个字符 。一般建议用 varchar 类型,字符数不要超过 2700 。
    8.【建议】时间类型尽量选取 timestamp 。因为 datetime 占用 8 字节,timestamp 仅占用 4 字节,但是范围为 1970-01-01 00:00:01 到 2038-01-01 00:00:00 。更为高阶的方法,选用 int 来存储时间,使用 SQL 函数 unix_timestamp() 和 from_unixtime() 来进行转换 。
    索引设计
    1. 【强制】InnoDB 表必须主键为 id int/bigint auto_increment,且主键值禁止被更新 。
    2. 【建议】主键的名称以 pk_ 开头,唯一键以 uk_ 开头,普通索引以 ix_ 开头,一律使用小写格式,以表名/字段的名称或缩写作为后缀 。
    3. 【强制】InnoDB 和 MyISAM 存储引擎表,索引类型必须为 BTREE;MEMORY 表可以根据需要选择 HASH 或者 BTREE 类型索引 。
    4. 【强制】单个索引中每个索引记录的长度不能超过 64KB 。
    5. 【建议】单个表上的索引个数不能超过 7 个 。
    6. 【建议】在建立索引时,多考虑建立联合索引,并把区分度最高的字段放在最前面 。如列 user_id 的区分度可由 select count(distinct user_id) 计算出来 。
    7. 【建议】在多表 join 的 SQL 里,保证被驱动表的连接列上有索引,这样 join 执行效率最高 。
    8. 【建议】建表或加索引时,保证表里互相不存在冗余索引 。对于 MySQL 来说,如果表里已经存在 key(a, b),则 key(a) 为冗余索引,需要删除 。


      推荐阅读