数据库基础

1 范式化设计

1.1 第一范式(1NF)无重复的列

定义

所谓第一范式(1NF)是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。如果出现重复的属性,就可能需要定义一个新的实体,新的实体由重复的属性构成,新实体与原实体之间为一对多关系。在第一范式(1NF)中表的每一行只包含一个实例的信息。简而言之,第一范式就是无重复的列。

image-20220919091324610

上面这张表就不符合第一范式,有重复的列,应该将 name-age 拆分成 name 和 age 两个列

1.2 第二范式(2NF)属性完全依赖于主键

定义

第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式(2NF)要求数据库表中的每个实例或行必须可以被惟一地区分。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。这个惟一属性列被称为主关键字或主键、主码。

image-20220919100708607

上面这张订单表,我们看到订单 id 为 1 的订单包含了两个产品,没有一个唯一的列被称为关键字,所以需要加上一个关键字主键

这张表需要优化成

订单表主表:

image-20220919100957960

订单表明细

image-20220919101125045

这样订单明细表中就依赖关键字 id,id 是唯一的主键,符合第二范式

1.3 第三范式(3NF)属性不依赖于其它非主属性

满足第三范式(3NF)必须先满足第二范式(2NF)。第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。

image-20220919091946856

上面这个订单表的设计,它依赖的商品信息过多,应该将商品信息拆分出来一张表单独存放

image-20220919092221757

商品表中存储商品相关信息,订单表中只存放商品 id,不存储名称等信息

总结

在日常工作中,我们在数据库设计方面基本上满足以上三个范式就可以了,至于BCNF范式第四范式(4NF) 作为了解即可

2 数据库常用类型

设计表时类型选择应该遵循以下几个规则

1、更小的字段,CPU 处理周期更少

2、简单就好

3、尽量避免 NULL

2.1 整数类型

类型字节数说明
tinyint1 字节对应 Java 中的 boolean 类型
smallint2 字节
mediumint3 字节
int4 字节
bigint8 字节对应 Java 中的 Long 类型

无符号

在数据库管理工具中我们进程见到无符号这个选项

image-20220919102426328

勾选了无符号,说明这个字段只能存储正数,有符号则存储范围是负数~正数

2.2 实数类型

MySQL 实数有三种类型,floatdoubledecimal

类型说明字节数
float单精度浮点数4 个字节
double双精度浮点数8 个字节
decimal(M, D)压缩的“严格”定点数M + 2 个字节

实数类型通常用于存储有小数的场景下,比如金额,重量等

博主在使用 MySQL 中这几个类型使用较少,这里给大家提供一些金额类字段存储的设计思路

我们存储金额一般会精确到分,比如 12.54 元,那么在存储的时候我们可以用整型,将 12.54 * 100 存储数据库中,取出的时候再进行相应的转化。有的同学可能会有疑问,这样做不是很麻烦。为什么这么做,这里就涉及到计算的精度问题了,如果计算时发现需要四舍五入,那么就可以考虑将数值乘以相应的倍数,100、1000 倍

2.3 字符串类型

类型长度范围字节数
char(M)0 <= M <=255M 个字节
varchar(M)0 <= M <= 65535M + 1 个字节
enum1 <= M <= 655351或者2 个字节
tinytext0 <= M <=255M + 2 个字节
text0 <= M <= 65535M + 2 个字节
mediumtext0 <= M <= 16777215M + 3 个字节
longtext0 <= M <= 4294967295M + 4 个字节

工作中常用的就是 char、varchar 和 text 类型

char

  • char(M) 类型一般需要预先定义字符串长度。如果不指定(M),则表示长度默认是1个字符。
  • char 是定长字符串,保存数据时,数据的实际长度比 char 类型声明的长度小,则会在右侧填充空格以达到指定的长度。当MySQL检索 char 类型的数据时,char 类型的字段会去除尾部的空格。
  • 定义 char 类型字段时,声明的字段长度即为 char 类型字段所占的存储空间的字节数。

varchar

  • varchar 使用时,必须指定长度,不指定则会报错
  • varchar 因为是变长字符串,需要额外地在长度列表上存放实际的字符长度:小于255为1个字节,大于255则要2个字节
  • varchar 是变长字符串,比如说 varchar(10),你存储了 “ok”,那么 varchar 实际存储就是两个字节,而 char(10) 则是存储了 10 个字节
  • 在不同的字符集下,varchar 的大小是不一样的,很多人可能会试过,varchar 最大可用存储 65535 个字节,为什么我设置 65535 会报错,这是因为我们存储通常用的是 utf8 字符集,在 utf8 字符集下,每个字符占用 3 个字节,所以在 utf8 字符集下 varchar(N) 中的N 最大为 (65535-1-2)/3

char 和 varchar 如何选择

1、存储很短的信息。比如门牌号码101,201……这样很短的信息应该用char,因为varchar还要占个byte用于存储信息长度,本来打算节约存储的,结果得不偿失。

2、固定长度的。比如使用uuid作为主键,那用char应该更合适。因为他固定长度,varchar动态根据长度的特性就消失了,而且还要占个长度信息。

3、十分频繁改变的column。因为varchar每次存储都要有额外的计算,得到长度等工作,如果一个非常频繁改变的,那就要有很多的精力用于计算,而这些对于char来说是不需要的。

扩展

4.0版本以下,varchar(20),指的是20字节,如果存放UTF8汉字时,只能存6个(每个汉字3字节)
5.0版本以上,varchar(20),指的是20字符,无论存放的是数字、字母还是UTF8汉字(每个汉字3字节),都可以存放20个,最大大小是65532字节

gbk:每个字符最多占用2个字节
utf8:每个字符最多占用3个字节

text

text 通常用于存储大文本,比如文章,评论等

3 设计规范

以下设计规范出自阿里巴巴开发手册

  1. 【强制】表达是与否概念的字段,必须使用 is_xxx 的方式命名,数据类型是 unsigned tinyint

(1 表示是,0 表示否)。

说明:任何字段如果为非负数,必须是 unsigned。

注意:POJO 类中的任何布尔类型的变量,都不要加 is 前缀,所以,需要在设置

从 is_xxx 到 Xxx 的映射关系。数据库表示是与否的值,使用 tinyint 类型,坚持 is_xxx 的

命名方式是为了明确其取值含义与取值范围。

正例:表达逻辑删除的字段名 is_deleted,1 表示删除,0 表示未删除。

  1. 【强制】表名、字段名必须使用小写字母或数字,禁止出现数字开头,禁止两个下划线中间只

出现数字。数据库字段名的修改代价很大,因为无法进行预发布,所以字段名称需要慎重考虑。

说明:MySQL 在 Windows 下不区分大小写,但在 Linux 下默认是区分大小写。因此,数据库名、

表名、字段名,都不允许出现任何大写字母,避免节外生枝。

正例:aliyun_admin,rdc_config,level3_name

反例:AliyunAdmin,rdcConfig,level_3_name

  1. 【强制】表名不使用复数名词。

说明:表名应该仅仅表示表里面的实体内容,不应该表示实体数量,对应于 DO 类名也是单数

形式,符合表达习惯。

  1. 【强制】禁用保留字,如 desc、range、match、delayed 等,请参考 MySQL 官方保留字。

  2. 【强制】主键索引名为 pk_字段名;唯一索引名为 uk_字段名;普通索引名则为 idx_字段名。

说明:pk_ 即 primary key;uk_ 即 unique key;idx_ 即 index 的简称。

  1. 【强制】小数类型为 decimal,禁止使用 float 和 double。

说明:float 和 double 在存储的时候,存在精度损失的问题,很可能在值的比较时,得到不

正确的结果。如果存储的数据范围超过 decimal 的范围,建议将数据拆成整数和小数分开存储。

  1. 【强制】如果存储的字符串长度几乎相等,使用 char 定长字符串类型。

  2. 【强制】varchar 是可变长字符串,不预先分配存储空间,长度不要超过 5000,如果存储长

度大于此值,定义字段类型为 text,独立出来一张表,用主键来对应,避免影响其它字段索

引效率。

  1. 【强制】表必备三字段:id, gmt_create, gmt_modified。

说明:其中 id 必为主键,类型为 bigint unsigned、单表时自增、步长为 1。gmt_create,

gmt_modified 的类型均为 datetime 类型,前者现在时表示主动创建,后者过去分词表示被

动更新。

  1. 【推荐】表的命名最好是加上“业务名称_表的作用”。

正例:alipay_task / force_project / trade_config

  1. 【推荐】库名与应用名称尽量一致。

  2. 【推荐】如果修改字段含义或对字段表示的状态追加时,需要及时更新字段注释。

  3. 【推荐】字段允许适当冗余,以提高查询性能,但必须考虑数据一致。冗余字段应遵循:

1)不是频繁修改的字段。

2)不是 varchar 超长字段,更不能是 text 字段。

正例:商品类目名称使用频率高,字段长度短,名称基本一成不变,可在相关联的表中冗余存

储类目名称,避免关联查询。

  1. 【推荐】单表行数超过 500 万行或者单表容量超过 2GB,才推荐进行分库分表。

说明:如果预计三年后的数据量根本达不到这个级别,请不要在创建表时就分库分表。

  1. 【参考】合适的字符存储长度,不但节约数据库表空间、节约索引存储,更重要的是提升检

索速度。

4 常用 SQL 语句

常用 SQL 语句可以看我之前写的一篇博客,里面详细记录了常用的查询语句

数据库SQL语句大全

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值