三大范式

范式 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。