1.范式标准
- 第一范式:1NF是对属性的原子性约束,要求属性具有原子性,不可再分解;
- 第二范式:2NF是对记录的惟一性约束,要求记录有惟一标识,即实体的惟一性;
- 第三范式:3NF是对字段冗余性的约束,即任何字段不能由其他字段派生出来,它要求字段没有冗余。
2.主键PK的取值方法
- PK是供程序员使用的表间连接工具,可以是一无物理意义的数字串, 由程序自动加1来实现。也可以是有物理意义的字段名或字段名的组合。不过前者比后者好。当PK是字段名的组合时,建议字段的个数不要太多,多了不但索引占用空间大,而且速度也慢。
3.正确认识数据冗余
- 主键与外键在多表中的重复出现, 不属于数据冗余,这个概念必须清楚,事实上有许多人还不清楚。非键字段的重复出现, 才是数据冗余!而且是一种低级冗余,即重复性的冗余。高级冗余不是字段的重复出现,而是字段的派生出现。
- 例如:商品中的“单价、数量、金额”三个字段,“金额”就是由“单价”乘以“数量”派生出来的,它就是冗余,而且是一种高级冗余。冗余的目的是为了提高处理速度。只有低级冗余才会增加数据的不一致性,因为同一数据,可能从不同时间、地点、角色上多次录入。因此,我们提倡高级冗余(派生性冗余),反对低级冗余(重复性冗余)。
4.中间表、报表和临时表
- 中间表是存放统计数据的表,它是为数据仓库、输出报表或查询结果而设计的,有时它没有主键与外键(数据仓库除外)。临时表是程序员个人设计的,存放临时记录,为个人所用。基表和中间表由DBA维护,临时表由程序员自己用程序自动维护。
5.完整性约束
- 域的完整性:用Check来实现约束,在数据库设计工具中,对字段的取值范围进行定义时,有一个Check按钮,通过它定义字段的值城。
- 参照完整性:用PK、FK、表级触发器来实现。
- 用户定义完整性:它是一些业务规则,用存储过程和触发器来实现。
6.三少原则
- 一个数据库中表的个数越少越好。只有表的个数少了,才能说明系统的E–R图少而精,去掉了重复的多余的实体,形成了对客观世界的高度抽象,进行了系统的数据集成,防止了打补丁式的设计;
- 一个表中组合主键的字段个数越少越好。因为主键的作用,一是建主键索引,二是做为子表的外键,所以组合主键的字段个数少了,不仅节省了运行时间,而且节省了索引存储空间;
- 一个表中的字段个数越少越好。只有字段的个数少了,才能说明在系统中不存在数据重复,且很少有数据冗余,更重要的是督促读者学会“列变行”,这样就防止了将子表中的字段拉入到主表中去,在主表中留下许多空余的字段。所谓“列变行”,就是将主表中的一部分内容拉出去,另外单独建一个子表。
7.索引设计规范
- 单表索引数目不能超过5个(注:聚集索引造成的存储和查询成本当索引过多时,性能降低很快)
- 一个字段的值范围很小不要设置索引,索引不生效同时浪费插入性能(注:比如性别,它的值范围很小,数据库进行的基本是全表扫描,没必要建索引)
- null值对索引是一大伤害,所以不要让索引的列有null值存在
- 尽量加索引的字段的数据类型小,也就是能用整数不用varchar能用短的varchar不用长的varchar,不要在text上设置索引
- 一个索引包含的字段数不能超过3个
- 尽量在静态数据上建立索引,频繁变动数据建索引,每次db都要考虑是否重建B+树
8.避免全表扫描
-
未创建索引 例如: select * from tbname where name=’?’ 如果name字段未创建索引,就会全表扫描
-
隐式转换 例如:select * from tbname where id=1234; 如果id字段是varchar类型,那么就算id字段上建立有索引,也还是会走全表扫描。
-
索引区分度问题:select * from tbname where status=1 and name=? ,status,sex这类字段的重复值过低,索引区分度超过30以上,优化器会认为status索引效率低,如果name字段没有索引的话,就会全表扫描
-
索引字段上使用函数 select * from tbname where date(create_time)=? create_time字段上使用了函数,将不会走索引,可以改成 create_time=date_format(?)这种形式
-
联合索引字段顺序, a,b字段创建联合索引,select * from tbname where b=? 不符合左前缀原则, 单独使用b字段无法使用索引,可改成 index(b,a);
9.分区分表
- 发现某个表的记录太多,例如超过一千万条,则要对该表进行水平分割。水平分割的做法是,以该表主键PK的某个值为界线,将该表的记录水平分割为两个表。若发现某个表的字段太多,例如超过八十个,则垂直分割该表,将原来的一个表分解为两个表。
10. 读写分离
- 主库发布binlog,从库订阅与消费binlog
- 主库只提供写,不建立索引,从库建立合理的索引。
11.使用缓存
- 缓存的用法是:
a.发生写请求时,先淘汰缓存,再写数据库
b.发生读请求时,先读缓存,hit则返回,miss则读数据库并将数据入缓存
(如有错误,欢迎指正!)