SQL基础 | 小册免费学

266 阅读4分钟

范式与反范式

三大范式

第一范式:具有原子性,数据库的每一列不可拆分 第二范式:主键列与非主键列遵循完全函数依赖关系 第三范式:非主键列之间没有传递函数依赖关系

第二范式(2NF)和第三范式(3NF)的概念很容易混淆,区分它们的关键点在于:

2NF:非主键列是否完全依赖于主键,还是依赖于主键的一部分(联合主键); 3NF:非主键列是直接依赖于主键,还是直接依赖于非主键列。即非主键列之间不存在依赖关系

粗略的理解,2NF,处理不合理的复合主键,3NF,处理单主键表的非主键列。

一般工作中,前第一、二范式大家都会遵守,但第三范式有事会被打破,实际工作中,越遵从范式化表涉及,表的拆分越细致,查询时需要关联的表越多。 而对于需要面对高并发的网站而言,复杂的关联查询是不允许的,一般都会采用冗余字段来减少关联查询。

此时我们可以适当反范式化设计(一般而言反范式设计,指的是第三范式),目的是减少查询时需要关联的表的数量从而提升查询性能。

范式化设计与反范式化设计之间的平衡:

遵守第三范式,查询复杂、麻烦、要么JOIN关联,要么内存匹配、甚至无法满足 不遵守第三范式,需要主动维护冗余数据、避免造成数据更新的不一致

数据类型的选择:

整数类型:

业务允许,尽量设置unsigned,无符号的,可以让正向范围翻倍,业务允许,可设置默认值 int(11)里的11和占用字节大小无关(对于数值类型来说,类型占用空间大小是固定的)11代表的是列宽,不够补零 注意各个类型的选取标准

数值类型选取时,规则是够用就好。跟索引有关(索引有页的概念,每页为16k固定容量,尽可能使每页(节点)存储的数据越多,减少磁盘IO)

通常来说 主键id用bigint age、height等普通数据用int delete、status、type等固定枚举的用tinyint

字符类型:

定长char: 字符类型的数字和实际大小有关。这里的数值与实际存储时大小的上限值有关,char(3)表示固定占用3个字符空间,存储值不够也会占用3个字符,但不能超过。

变长varchar: varchar(255),表示最多能存储255字节,但是varchar会分出一部分空间存储实际数据实际的长度,以实际存储的值为准。

char VS varchar char长度固定,不需要考虑边界问题,读写效率高于varchar,适合存储长度固定,频繁读写的数据 varchar长度不固定,但可以通过varchar(10)来指定上限,适合存储长度波动,更新不频繁的数据 char的存储长度不够灵活,而varchar则需要浪费1~2个字节来存储当前值的实际长度,且更新会导致重新计算

char是定长,像一个数组一样,长度固定,char(3),说明一定为3个字节,加入一个字节代表3个格子,则再找第三个数据时,只需要从初始位置跨6个格子即可。而varchar(3)只代表上限,实际不一定占用3个字节,所以不能通过直接计算得到位置。

char适用场景:电话号码、身份证、有的公司时间也用char存储 varchar适用场景:个人介绍等

小数类型:

folat 4个字节 非精准 double 8个字节 非精准 decimal 每4个字节存9个数字,小数点占一个字节 精准

decimal大小:123456789.987654321,用decimal(18,9),占9个字节,前后4个字节,小数点一个字节。decimal效率不如float和double

最小单位直接存分时,可以用数值类型存储,无精度问题

时间类型:

date 3个字节 1000-9999 无时分秒 time 3-6个字节 -838 - 838 datetime 5-8个字节 1000-9999 有时分秒 timestamp 4-7个字节 1970-2038 有时分秒

datetime和timestamp区别: 时间范围不同,datetime更大,内存稍大 timestamp时间会根据时区变化,set time_zone

类型选择小结: 更小的通常更好 简单适合够用就好 尽量避免null(设置NOT NULL,除非业务要求可能NULL) 如果确定不会出现负数,可以使用unsigned

NOT NULL:不能为NULL,否则报错 DEFAULT ‘xx’ : 不传值时使用xx为默认值 可以传NULL NOT NULL DEFAULT ‘xx’:不能传NULL

本文正在参与「掘金小册免费学啦!」活动, 点击查看活动详情