程序员的MySQL手册(三):数据库设计
这一篇我们会讲解数据库设计的准则,介绍常见的数据类型,以及数据库范式和反范式,和他们的应用。
数据库设计的准则
- 小即是美:用可以表示要存储的数据的最小的类型。小的类型可以更快,因为它们会占用更少的磁盘、内存、CPU缓存空间,通常也只需要更少的CPU指令来处理
- 简单:处理简单的数据类型可以使用更少的CPU指令
- 尽量避免NULL(仅MyISAM适用)
数据类型
MySQL提供这些数据类型:
- 布尔
- BOOL
- 数字
- 整数
- SMALLINT 占用8个bit,表示范围为 -128~127
- MEDIUMINT 占用26个bit,表示范围为 -8388608 to 8388607
- INT 占用32个bit,表示范围为 -2147483648 to 2147483647
- BIGINT 占用64个bit,表示范围为 -9223372036854775808 to 9223372036854775807
- 浮点数
- FLOAT 单精度浮点数
- DOUBLE 双精度浮点数
- DECIMAL DECIMAL一般用来表示金钱
- 整数
- 二进制
- BLOB 以二进制方式存储,如照片等
- TINYBLOB
- SMALLBLOB
- BLOB
- MEDIUMBLOB
- LONGBLOB
- BLOB 以二进制方式存储,如照片等
- 字符串
- VARCHAR 变长的字符串,一般会配合一个最大长度,例如
VARCHAR(32)
- CHAR 固定长度的字符串
- TEXT 以纯文本方式存储字符串
- TINYTEXT
- SMALLTEXT
- TEXT
- MEDIUMTEXT
- LONGTEXT
- VARCHAR 变长的字符串,一般会配合一个最大长度,例如
- 时间
- DATETIME 表示范围是 ‘1000-01-01 00:00:00’ to ‘9999-12-31 23:59:59’
- TIMESTAMP 表示范围是 ‘1970-01-01 00:00:01’ UTC to ‘2038-01-19 03:14:07’ UTC
- 其它如BIT
对应的UNSIGNED,就可以把负数可以表示的范围用于表示正数
注意,MySQL中的int往往带有一个数字,例如 INT(11),这不是说INT占11bit,而是表示在交互式命令行中,该列占11个字符长
而日常开发中我们常用的数据类型有这些:
- INT,比如主键就会用它,更合理的是设置为 UNSIGNED INT
- VARCHAR,绝大部分的字符串都会用VARCHAR来存储
- BOOL,布尔值
- TINYINT,有多个可选值时,会使用TINYINT来存储可选情况
- TEXT,存储大篇文章时
- DATETIME,存储时间一般都会用这个
范式和反范式
根据数据库范式来设计,我们的数据库表会有如下特征:
- 每一列都是不可切分的最小数据
- 所有表都有主键,其它字段都依赖于主键
- 没有重复数据,引用的数据通过外键引用
反范式就是说不遵循这个规定。
实际上日常开发工作中,是反范式和范式结合遵循的,两者都没有完全遵循。为什么呢?因为如果完全遵循范式,大量使用外键之后, 当并发一上去,数据库的负载会迅速上升,所以日常开发中,一般会舍弃第三条,选择冗余一部分数据,例如,如果要在某个表中 引用user id,我们不会使用外键,而是建立一个列,专门存储user_id。另外一个原因就是,数据库的几个范式提出时间都比较古老, 那个时候磁盘什么的还很贵,所以要节省,而现在,磁盘已经很便宜了,相比之下,为了节省磁盘而需要付出的性能代价却更高,因此 就不会选择遵循无冗余的范式了。
系列目录:
- 程序员的MySQL手册(一): 安装,基本配置
- 程序员的MySQL手册(二): 监控与benchmark
- 程序员的MySQL手册(三):数据库设计
- 程序员的MySQL手册(四):索引设计
- 程序员的MySQL手册(五):索引优化
参考资料:
更多文章
本站热门
- socks5 协议详解
- zerotier简明教程
- 搞定面试中的系统设计题
- frp 源码阅读与分析(一):流程和概念
- 用peewee代替SQLAlchemy
- Golang(Go语言)中实现典型的fork调用
- DNSCrypt简明教程
- 一个Gunicorn worker数量引发的血案
- Golang validator使用教程
- Docker组件介绍(二):shim, docker-init和docker-proxy
- Docker组件介绍(一):runc和containerd
- 使用Go语言实现一个异步任务框架
- 协程(coroutine)简介 - 什么是协程?
- SQLAlchemy简明教程
- Go Module 简明教程