三大范式
范式 Normal Format
第一范式1NF:
字段原子性,字段不可再分割。
关系型数据库,默认满足第一范式
第二范式:
消除对主键的部分依赖。
部分依赖:某一字段依赖复合主键的一部分(只有复合主键才会产生部分依赖)
第三范式:
消除对主键的传递依赖(c依赖b,b依赖主键,则c对主键传递依赖)
新增一张表,减少了数据的冗余。
null
尽可能使用 not null:
非null字段的处理要比null字段的处理高效些,且不需要判断是否为null。
null在MySQL中不好处理,存储需要额外空间(MySQL中每条记录都需要额外的存储空间,表示每个字段是否为null)。
运算需要特殊的运算符:
通过is null和is not null来判断字段是否为null。
null参与运算,结果都为null。
通常使用特殊的数据进行占位,比如int not null default 0,string not null default ''
null 值反映在索引中的排列规则是:
null值会被归到一块:
如果是升序的话,null值被归到数据页的前端。
如果是降序的话,null值被归到数据页的尾端。
如果有多条null值数据,则按先来后到的顺序依次排列。
空值与 null:
在进行count()统计某列的记录数的时候,如果采用的NULL值,会被系统自动忽略掉,但是空值('')是会进行统计到其中的。
空值('')是不占用空间的,MySQL中的 NULL 是占用空间的。
NULL值的检索只能使用 is null / is not null / <=>,不能使用=,<,>这样的运算符(mysql中可以用a <=> NULL 表示查找 a is NULL的行)
or
对于具有2个用or连接条件的语句,isolate col index(独立索引)有一定优势
这种情况下multi col index(联合索引)将会导致全表扫描,而前者可以用到index merge的优化。
短索引
如果一个索引中包含了数据类型为字符串的,那么可以为这一列指定长度。因为,对于很多的字符串来说,前几个就可以确定该字符是唯一的了。
CREATE INDEX index_name ON table_name (column(10));
不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。
数值与字符串
尽量使用数字型字段(整数:储存空间固定,少,运算快):
对于字符串,引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
int类型带长度(int(11)):
不影响存取值,即使设定的值超出了长度的范畴,也能存。
如果没有达到设定的长度,则使用空格自动填充到设定的长度。
char(64)(因其长度固定,char的存取速度快得多,方便程序的存储与查找):
不可变字符,设定的长度就是规定当前字段能存的数据的最大长度(64个字符)。
若超出长度,则会报错,若没有达到长度,使用空格填充到设定的长度。
varchar(64)(储存空间可变):
可变字符,设定的长度同样是规定当前字段能存的数据的最大长度。
若超出长度,则会报错,若没有达到长度,不会使用空格填充,实际多长就是多长。
储存地址
IP varchar(15) 与 int 之间的转换:
inet aton('');
inet ntoa('');
a:address
n:number
数值储存
金额存储:
1. decimal(8,2):有两位小数的定点数。
2. 整数存储,小单位,大数值。
定点数:
占用空间随数的增长而增长。
浮点数:
空间固定,数值变大到一定程度会向后浮动,舍弃尾部,丢失精度。
其他优化
不要在字段上进行运算(id + 1 > 10 之类),否则索引失效。
like语句操作:
like "%aaa%" 不会使用索引而 like "aaa%" 可以使用索引。
对于连续的数值,能用 between 就不要用 in。
limit:
尽量不要出现大的offset(这样会查出大量数据而只使用少量数据,跳过大量已经查询的数据,查询效率降低)
尽量使用条件过滤筛选后,再使用limit。