数据库建表时,对于字段的数据类型的选择

本文是《数据库设计那些事》的笔记和思考。

有如下几种情形:

  • 当字段可选择多个类型时(比如生日字段,可以用时间戳,即整数类型,可以用字符串 类型,也可以用日期 类型):整数、二进制 优于 日期 优于 字符串。

原因:

一、在对数据进行比较(查询条件、JOIN条件及排序)操作时:同样的数据,字符处理往往比数字要慢。

二、在数据库中,数据处理以页为单位,比如 mysql 16k字节一个页。而列的长度越小,在一个页中存储的数据就会越多。在加载相同多的数据的时候,如果列越小,加载的页就会越少。I/O的性能就会提高。

  • 当字段要在 char 和 varchar 之间取舍的时候,有如下几条原则:
  1. 如果列中所要存储的数据长度是确定,且基本一致的,比如身份证字符串,则应该使用char;否则应该使用 varchar。
  2. 如果列中的最大数据长度小于50个字节,且这个列使用频繁,则应该使用char。如果列中的最大数据长度小于50个字节,但是很少使用,则基于减少空间和节省I/O的角度考虑,还是可以使用 varchar的。
  3. 一般不宜定义大于50字节的char类型列。

解释:每一个 varchar 的列,除了存储数据需要的字节之外,还需要额外的字节存储数据的实际长度。在检索数据时,也需要确定数据的起止位置。

所以,对于 utf-8 编码的字符串,超过15个字符,就要考虑使用 varchar。

不过生活总是充满各种反转和意外的,对于char 和 varchar 应该如何选择,我看到一篇博文上说和存储引擎的选择有很大关系。说的似乎也很有道理:

InnoDB 存储引擎 建议使用VARCHAR类型。
对于InnoDB数据表,内部的行存储格式没有区分固定长度和可变长度列(所有数据行都使用指向数据列值的头指针),因此在本质上,使用固定长度的CHAR列不一定比使用可变长度VARCHAR列简单。因而,主要的性能因素是数据行使用的存储总量。由于CHAR平均占用的空间多于VARCHAR,因此使用VARCHAR来最小化需要处理的数据行的存储总量和磁盘I/O是比较好的。

这就很让人纠结了。到底该听谁的?外事不决问google,然后我就在stackoverflow 那发现一个很有启发性的建议:

MySQL’s indexing is good enough that the difference in performance is tiny. It’s only when tables get large ( meaning on the order of 10**9 rows or more ) that the performance difference between VARCHAR() and CHAR() starts to be meaningful.

It’s smarter to spend your precious development time making your app nice enough that you have a chance of attracting gazillions of users. And when you have them, you probably can get a really competent database administrator to help you fix your minor inefficiencies.

大意就是,mysql的速度已经很快了,尤其是使用了索引之后,选 char 和 varchar 对于性能的提升根本微不足道。老老实实把你的 app 做大才是重点,别整天整这些有的没的。

这个兄弟说话很对我胃口啊,看起来也是个全栈工程师。是贫道执迷了。这个知识点先跳过。

  • 对于decimal和 float类型有如下原则:
  1. decimal用于存储精确数据,而float只能用于存储非精确数据。故精确数据只能选择用decimal类型。
  2. 由于float类型的存储开销一般比decimal小,故非精确类型优先选择float。

你可能感兴趣的:(数据库建表时,对于字段的数据类型的选择)