计算机系统应用教程网站

网站首页 > 技术文章 正文

MySQL实战——表结构设计之数字类型

btikc 2025-01-03 14:24:04 技术文章 24 ℃ 0 评论

整型

不建议刻意去用 unsigned 属性,因为在做一些数据分析时,SQL 可能返回的结果并不是想要得到的结果。

比如在财务的场景下,经常会做一些加减操作。

MySQL 要求 unsigned 数值相减之后依然为 unsigned,否则就会报错。

为了避免这个错误,需要对数据库参数 sql_mode 设置为 NO_UNSIGNED_SUBTRACTION,允许相减的结果为 signed。


浮点类型和高精度型

MySQL 之前的版本中存在浮点类型 Float 和 Double,但这些类型因为不是高精度,也不是 SQL 标准的类型,所以在真实的生产环境中不推荐使用,否则在计算时,由于精度类型问题,会导致最终的计算结果出错。

更重要的是,从 MySQL 8.0.17 版本开始,会提示警告,提醒将在之后版本中废弃浮点类型。

而数字类型中的高精度 DECIMAL 类型可以使用,当声明该类型列时,可以(并且通常必须要)指定精度和标度。

然而,在海量并发的互联网业务中使用,金额字段的设计并不推荐使用 DECIMAL 类型,而更推荐使用 INT 整型类型。


业务表结构设计实战

整型类型与自增设计

在业务中,整型类型的常见且重要的使用用法是作为表的主键,即用来唯一标识一行数据。

整型结合属性 auto_increment,可以实现自增功能,但在表结构设计时用自增做主键,要注意以下两点,若不注意,可能会对业务造成灾难性的打击:

  • 用 BIGINT 做主键,而不是 INT;
  • 自增值并不持久化,可能会有回溯现象(MySQL 8.0 版本前)。

INT 的范围最大在 42 亿的级别,在真实的互联网业务场景的应用中,很容易达到最大值。例如一些流水表、日志表,每天 1000W 数据量,420 天后,INT 类型的上限即可达到。

因此,用自增整型做主键,一律使用 BIGINT,而不是 INT。

当达到 INT 上限后,再次进行自增插入时,会报重复错误,MySQL 数据库并不会自动将其重置为 1。

鉴于自增值不持久化的问题,其实,在海量互联网架构设计过程中,为了之后更好的分布式架构扩展性,不建议使用整型类型做主键,更为推荐的是字符串类型。

资金字段设计

在海量互联网业务的设计标准中,并不推荐用 DECIMAL 类型,而是更推荐将 DECIMAL 转化为 整型类型。也就是说,资金类型更推荐使用用分单位存储,而不是用元单位存储。如1元在数据库中用整型类型 100 存储。

类型 DECIMAL 是通过二进制实现的一种编码方式,计算效率远不如整型来的高效。因此,推荐使用 BIG INT 来存储金额相关的字段。

字段存储时采用分存储,即便这样 BIG INT 也能存储千兆级别的金额。这里,1兆 = 1万亿。

这样的好处是,所有金额相关字段都是定长字段,占用 8 个字节,存储高效。另一点,直接通过整型计算,效率更高。

注意,在数据库设计中,我们非常强调定长存储,因为定长存储的性能更好。

尤其是在更新频繁的场景中,定长的记录能够利用原有的空间,而非定长的记录将对原有空间进行标记删除,然后重新分配空间写入更新的记录。将会造成磁盘空洞,这个空间后续将变成碎片空间,无法继续使用,除非人为地进行表空间的碎片整理。

总结

  1. 不推荐使用整型类型的属性 Unsigned,若非要使用,参数 sql_mode 务必额外添加上选项 NO_UNSIGNED_SUBTRACTION;
  2. 自增整型类型做主键,务必使用类型 BIGINT,而非 INT,后期表结构调整代价巨大;
  3. MySQL 8.0 版本前,自增整型会有回溯问题;
  4. 当达到自增整型类型的上限值时,再次自增插入,MySQL 数据库会报重复错误;
  5. 不要再使用浮点类型 Float、Double,MySQL 后续版本将不再支持上述两种类型;
  6. 账户余额字段,设计是用整型类型,而不是 DECIMAL 类型,这样性能更好,存储更紧凑

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表