程序员的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
  • 字符串
    • VARCHAR 变长的字符串,一般会配合一个最大长度,例如 VARCHAR(32)
    • CHAR 固定长度的字符串
    • TEXT 以纯文本方式存储字符串
      • TINYTEXT
      • SMALLTEXT
      • TEXT
      • MEDIUMTEXT
      • LONGTEXT
  • 时间
    • 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。另外一个原因就是,数据库的几个范式提出时间都比较古老, 那个时候磁盘什么的还很贵,所以要节省,而现在,磁盘已经很便宜了,相比之下,为了节省磁盘而需要付出的性能代价却更高,因此 就不会选择遵循无冗余的范式了。

系列目录:


参考资料:


更多文章
  • 选择合适的技术栈
  • Golang的template(模板引擎)简明教程
  • 毕业三年,一路走来
  • 代码的坏味道
  • 消息分帧(字符串设计或协议设计)的两种形式
  • C, Go, Python的错误处理和异常机制杂谈
  • 好的命名是最好的文档
  • 读《系统之美:决策者的系统思考》
  • Linux高分屏支持
  • GCC默认的头文件搜索路径
  • 读《远见-如何规划职业生涯3大阶段》
  • 后端工程师学前端(五): SASS
  • 后端工程师学前端(四): CSS进阶(盒子模型)
  • 读《投资中最简单的事》
  • 后端工程师学前端(三): CSS进阶(特指度、单位和字体族)