一、范式化设计
1NF:每一列不可再分;
2NF:单一职责;每张表只干一件事;要求通过主键可以确定所有其他字段;
3NF:消除依赖传递/消除冗余字段;要求A表不包含B表的非主键字段;最多包含B表的主键字段;
范式数字越大,要求一个表的功能越单一;冗余的字段越少;
二、反范式化设计及实现
1、范式化设计可以提高表数据的修改效率;
2、范式、反范式如何选择?
-- 根据情况适当选择;
-- 适当反范式化;比如冗余简单字段,可以提高查询效率;
3、在高并发情况下,如何应对大量的数据计数操作?
-- 背景:mysql数据库在做update操作时,会对当前行数据加一个互斥锁,影响效率;
-- 可以设计若干槽(多行)数据来计数,分散热点数据,减少对同一行资源争抢的线程数;
三、表结构字段类型优化
1、更小类型范围,通常更好;
-- 更小的字段,占用的存储空间更少;--> CPU处理时间更短;
2、简单就好;
-- 结构越简单的字段类型,使用起来效率更高;
-- 与1的理由相同;
3、尽量避免NULL;
-- 尽量勾选上 【不是null】,避免难以优化;
-- 性能优化有限;
-- 如果涉及索引,就尽量避免null;
4、MySQL支持的数据类型;
整数类型 | tinyint | smallint | mediumint | int | bigint | integer |
1 Byte = 8 位 | 2 Byte = 16 位 | 3 Byte = 24 位 | 4 Byte = 32 位 | 8 Byte = 64 位 | 相当于 int | |
浮点数类型 | float(非精确数) | double(非精确数) | decimal(精确数) | | | |
4 Byte = 32 位 | 8 Byte = 64 位 | 字符串 65 个数字 | ||||
字符串类型 | char | varchar | blob | text | enum | set |
定长度; 更节省空间,不需要单独记录数据长度; | 不定长度; 需要有1~2个额外的字段记录数据长度; | 1、这两个类型占用的空间太大,不利于sql性能调优; 2、如果使用该类型的字段;建议将这一列单独分到一张表中,主表只记录它的主键; 3、blob:存储的是二进制数据,没有字符集和排序规则; 4、text:存储的是文本,有字符集和排序规则; | 1、枚举,用数字标识一些指定的字符串,好处是避免保存许多重复的字符串; 2、在设计表的时候可以指定该列的枚举值:["fish","apple","dog"]等; 3、插入数据的时候,只要保存数字即可; 4、枚举元素只能是字符串; | |||
日期和时间类型 | datetime | timestamp | ||||
1、存储跨度长: 1001年~9999年 2、只精确到秒 | 1、1970年~2038年; 2、只精确到秒 |
备注:MySQL 支持数据值为null;所以与数据表映射的java类型要求是包装类;基本数据类型不支持值为null;
5、无符号 unsigned
-- 字段的存储大小和符号没有关联;
-- 用 1字节 的tinyint举例:
-- 有符号:是一个默认选项,此时字段的范围是从 -128 ~ 127;
-- 无符号:需要手动勾选,此时字段的范围是 0 ~ 255;
-- 可见如果勾选无符号,那么砍掉负数的范围,将正数的范围 *2;
6、长度
-- 设置整型字段类型的不同长度,在存储层是无差别的;
-- 只是限制显示时的位数;
7、数据量特别大,要存金额,要求准确度,要求效率,如何设计?
-- 使用 bigint存储1/10000的精度;
-- 将数据放大来存储小数位;
8、char 和 varchar 如何选择?
-- 字符串列:数据长度长的很长,短的很短,就要使用varchar;
-- 字符串列:数据长度是确定的;电话号,密码,hash值等,就要使用char;
9、MySQL 时间类只能存储到秒;
-- 想要存储更小的粒度,可以使用时间戳或者字符串;
四、命名规范
1、索引命名
-- 主键索引:pk_XXX;
-- 唯一索引:uk_XXX;
-- 普通索引:idx_XXX;
五、索引
1、什么是索引?
-- 帮助MySQL数据库高效查询的数据结构;
2、索引的本质:
-- 数据结构;
3、索引的作用:
-- 提高查询速度;
4、InnoDB存储引擎支持的索引:
-- B+ 树索引:(关键)
-- 全文索引:
-- hash 索引(内部):
-- 范围查找、排序、组合索引、hash冲突;
5、树
名称 | 说明 |
二叉树 | 1、左子节点都小于根节点 2、右子节点都大于根节点 |
AVL树(平衡二叉树) | 1、左右两个子树的高度差最大为 1 ; 2、左右两个子树都是平衡二叉树; 3、尽量压缩树的高度; |
B树 | 1、B-树;多叉树;先满足二叉树; 2、平衡树; 3、数据存储在非叶子节点和叶子节点上; 4、 |
B+树 | 1、多叉树;先满足二叉树; 2、平衡树; 3、非叶子节点只存放索引信息;而且根据索引大小排好了顺序; 4、每个索引节点可存储多个索引,每个索引都指向一个叶子节点"页"; 5、所有数据均存放在叶子节点的“页”上; 6、这些“页”首尾相连; 7、每个叶子节点通过单向链表方式连接;方便进行范围查找; 8、在MySQL中,B+树的叶子节点使用双向链表连接;方便排序; 9、数据量较小,每次返回的数据个数较多,减少io次数; 10、B+树具有很高的“扇出”,通常超过100个,在查找数据时,可以有效减少io; -- 扇出:每个索引节点指向叶子节点的指针; -- 扇出数:索引节点可存储的最大关键字个数 + 1; |
B*树 | 1、多叉树;先满足二叉树; 2、平衡树; 3、非叶子节点存放的索引数据也加了一个指针;查询索引速度快; |
6、时间复杂度
查找方式 | 平均次数 | 最坏情况 | 时间复杂度 |
顺序查找 | (1+n)/2 次 | n次 | O(n) |
二分查找 | (1+2+2+3+3+3+3+4+4+4)/10 = 2.9次 | 4次 | O(log n) |