资讯专栏INFORMATION COLUMN

你应该知道的数据库数据类型及其设计原则

MudOnTire / 378人阅读

摘要:整数类型整数类型有,分别使用位存储空间。实数类型实数类型有,分别占用,字节。简单数据类型的操作需要更少的周期。

1. 整数类型

整数类型有:tinyint、smallint、mediumint、int、bigint,分别使用 8、16、24、32、64 位存储空间。它们可以存储的值范围从 -2 的 (n-1) 次方到 2 的 (n-1) 次方 -1,n 是存储空间的位数。

整数有可选的 unsigned 属性(无符号类型),表示不允许有负值,因此可以使正数上限提高一倍。

有符号和无符号类型使用相同的存储空间,并具有相同的性能,因此可以根据实际情况选择合适的类型。

2. 实数类型

实数类型有:FLOAT、DOUBLE ,分别占用 4,8 字节。

如果插入值的精度(即:数字总位数)高于实际定义的精度,系统会自动进行四舍五入处理,使值的精度达到要求。

其中 DECIMAL 也可以用来指定精度,并且它比 FLOAT 和 DOUBLE 更适合做精确计算。在本文就不做详细介绍了,如果有人想了解的话可以给我留言,我下次再写。

3. 字符串类型

字符串类型有:

VARCHAR

CHAR

BLOB

TEXT

由于 BLOB 和 TEXT 不常用且由于篇幅问题,就不展开描述了。本文主要对 VARCHAR 和 CHAR 进行介绍,它们的区别如下表:

对比内容 VARCHAR CHAR
是否固定长度
存储上限字节 65535 255
保存或检索值时,是否删除字符串末尾空格
超过设置的范围后,字符串是否会被截断

除了以上不同之外,VARCHAR 还需要额外使用 1 个或 2 个字节来记录字符串长度。如果列的最大长度小于或等于 255 字节,则使用 1 个字节,否则使用 2 个字节。

由于 VARCHAR 是变长的,所以在 update 时,可能使行变得比原来更长,这就导致需要进行额外的工作。如果一个行占用的空间增加,并且在页内没有更多空间可以存储,在这种情况下,不同存储引擎的处理方式不一样的。例如:MyISAM 会将行拆分为不同的片段存储,InnoDB 则需要分裂页来使行可以放进页内。

在选择使用场景上,重点要抓住 VARCHAR 是变长,CHAR 是定长的特点。

比如在这些情况更适合使用 VARCHAR:

字符串的最大长度比平均长度大很多;

字段更新次数少(所以碎片不是问题);

使用了像 UTF-8 这样复杂的字符集,每个字符都使用不同的字节数进行存储。

而在这些情况则更适合使用 CHAR:

存储很短的字符串(而 VARCHAR 还要多一个字节来记录长度,本来打算节约存储的现在反而得不偿失)

定长的字符串(如 MD5、uuid);

需要频繁修改的字段。因为 VARCHAR 每次存储都要有额外的计算,得到长度等工作;

这里抛出一个小问题:使用 VARCHAR(5) 和 VARCHAR(200) 来存储 ‘hello’ 的空间开销是一样的。那么使用更短的列有什么好处呢?(思考几秒钟?)

答案:节约内存,因为更长的列会消耗更多的内存。MySQL 通常会分配固定大小的内存块来保存内部值。尤其是使用内存临时表进行排序或操作时会特别糟糕。在利用磁盘临时进行排序时也同样糟糕。

所以最好的策略是只分配真正需要的空间。

4. 日期和时间类型

下面表格是 TIMESTAMP 和 DATETIME 的一些对比:

对比内容 TIMESTAMP DATETIME
占用字节 4 8
时间范围 1970-01-01 08:00:01 ~ 2038-01-19 11:14:07 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59
存储的数据是否随时区变化

如果在插入数据时,没有指定第一个 TIMESTAMP 列的值,MySQL 则将这个列设置为当前时间,同时 TIMESTAMP 比 DATETIME 的空间效率更高。

最后,网上有很多讨论,时间到底要使用 INT、TIMESTAMP、DATETIME 哪种类型更适合。我认为这没有一个固定答案,具体可以参考文章:《选择合适的 MySQL 日期时间类型来存储你的时间》,我放在原文链接里面了。

5. 设计合理的数据类型

提供给大家 3 点设计原则:

更小的通常更好

简单就好

尽量避免 NULL

下面对其详细说明一下:

一般情况下,应该选择可以正确存储数据的最小数据类型,因为它们占用更少的磁盘、内存和 CPU 缓存,并且处理时需要的 CPU 周期也更少。

简单数据类型的操作需要更少的 CPU 周期。例如,整型比字符操作代价更低,因为字符集和校对规则(排序规则)使字符比较比整型比较更复杂。

通常情况下,最好指定列为 NOT NULL,除非真的需要存储 NULL 值。因为可为 NULL 的列会使索引、索引统计和值比较都更复杂。可为 NULL 的列会使用更多的存储空间,在 MySQL 里也需要特殊处理。

当可为 NULL 的列被索引时,每个索引需要一个额外的字节,在 MyISAM 里甚至还可能导致固定大小的索引变成可变大小的索引。通常把可为 NULL 的列改为 NOT NULL 带来的性能比较小,所以在优化时没有必要先在现有表里修改这种情况。

参考:
《高性能 MySQL》

欢迎关注微信公众号「不只Java」,后台回复「电子书」,送说不定有你想要的呢

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/72517.html

相关文章

  • php设计模式

    摘要:我们今天也来做一个万能遥控器设计模式适配器模式将一个类的接口转换成客户希望的另外一个接口。今天要介绍的仍然是创建型设计模式的一种建造者模式。设计模式的理论知识固然重要,但 计算机程序的思维逻辑 (54) - 剖析 Collections - 设计模式 上节我们提到,类 Collections 中大概有两类功能,第一类是对容器接口对象进行操作,第二类是返回一个容器接口对象,上节我们介绍了...

    Dionysus_go 评论0 收藏0
  • php设计模式

    摘要:我们今天也来做一个万能遥控器设计模式适配器模式将一个类的接口转换成客户希望的另外一个接口。今天要介绍的仍然是创建型设计模式的一种建造者模式。设计模式的理论知识固然重要,但 计算机程序的思维逻辑 (54) - 剖析 Collections - 设计模式 上节我们提到,类 Collections 中大概有两类功能,第一类是对容器接口对象进行操作,第二类是返回一个容器接口对象,上节我们介绍了...

    vspiders 评论0 收藏0
  • 第6章:可维护性软件构建方法 6.1可维护性度量和构造原则

    摘要:设计方案的容易改变这就是所谓的软件构建的可维护性,可扩展性和灵活性。这也可能表明类型或方法可能难以维护。基于源代码中不同运算符和操作数的数量的合成度量。对修改的封闭这种模块的源代码是不可侵犯的。 大纲 软件维护和演变可维护性度量模块化设计和模块化原则OO设计原则:SOLIDOO设计原则:GRASP总结 软件维护和演变 什么是软件维护? 软件工程中的软件维护是交付后修改软件产品以纠正故障...

    chanjarster 评论0 收藏0
  • 后端好书阅读与推荐(续)

    摘要:续前文后端好书阅读与推荐,几十天过去了,又看了两本好书还有以前看过的书,这里依然把它们总结归纳一下,加入一些自己的看法有用的链接和可能的延伸阅读,并推荐给需要的同学。 续前文 后端好书阅读与推荐 - Mageek`s Wonderland ,几十天过去了,又看了两本好书(还有以前看过的书),这里依然把它们总结归纳一下,加入一些自己的看法、有用的链接和可能的延伸阅读,并推荐给需要的同学。...

    刘福 评论0 收藏0
  • 后端好书阅读与推荐(续)

    摘要:续前文后端好书阅读与推荐,几十天过去了,又看了两本好书还有以前看过的书,这里依然把它们总结归纳一下,加入一些自己的看法有用的链接和可能的延伸阅读,并推荐给需要的同学。 续前文 后端好书阅读与推荐 - Mageek`s Wonderland ,几十天过去了,又看了两本好书(还有以前看过的书),这里依然把它们总结归纳一下,加入一些自己的看法、有用的链接和可能的延伸阅读,并推荐给需要的同学。...

    OnlyLing 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<