暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL表结构设计篇之数据类型

PHP Garden 2021-06-24
1468

在进行表结构设计时,数字类型是最常见的类型之一,但数字类型不一定简单。

  • tinyint(1)
    和 tinyint(3) 有什么区别吗?

  • int类型作为数据表主键是否合理?有什么风险?

  • 微信支付以及支付宝的表示金额的为什么要使用分为基础单位?

带着这几个问题,让我们一起思考什么是最佳实践吧。

数字类型之整形

MySQL数据库支持的整形:

tinyint smallint mediumint int bigint

取值范围
类型占用空间(Byte)最小值 , 最大值(signed)最小值 , 最大值(unsigned)
tinyint18-2^7 , 2^7 -1 0 , 2^8-1
smallint216-2^15 , 2^15-10 , 2^16-1
mediumint324-2^23 , 2^23 -1 0 , 2^24-1
int432-2^31 , 2^31 -1 0 , 2^32-1
bigint864-2^63 , 2^63 -1 0 , 2^64-1

常用的类型可能就 tinyint 、int 、bigint。

tinyint类型,占用空间1字节,在 signed 情况下,为 (-2^7,2^7-1),即 -128,127。

这里为什么不是 -2^7? 这里要说明一下,在数据类型中,有 signed 和 unsigned属性,在 signed的情况下,数据库需要分配一位去存储数值的正负号。

2^7 - 1,是为什么呢?这是因为 0 的原因。

那么tinyint(1) 和 tinyint(3)有什么区别呢?

这里没什么区别。不论是 tinyint(1)还是 tinyint(3),在 signed情况下,存储的数字最大值都是 127!

有一种说法是:跟 填充零有关系,目前没测试出来。

ps:

  • 在实际工作过程中,设置 长度,也仅仅是提示说明。

  • 在设计数据表的时候,需要考虑好是否要使用unsigned,但是当查询时,有使用运算的情况,对应字段如果出现负数,会引发MySQL的报错:计算结果超出范围,这时候需要修改 sql_mode 的值 为 NO_UNSIGNED_SUBTRACTION,允许计算结果为 signed。

数字类型之浮点型

MySQL 的浮点型为 float 和 double 类型。但是因为这些类型不是高精度,并且从 MySQL 8.0.17 开始,当设置 float 和 double 时,会提示将在以后的版本废弃浮点类型。

数字类型之高精度型

MySQL 的高精度型为 decimal类型,声明该类型必须要指定精度和标度。通常用户表示账户余额等业务。

amount decimal(2,2)

其中,2表示精度,指扣除小数点后的数字数。2表示小数点后的位数。如下:

0.12    // 可存储

2.2     可存储

11 可存储

3.23  // 提示超出范围

最佳实践

1、int 作为数据表主键时,自增设计

我们在设计表时,可能喜欢用 id + auto_increment ,以实现自增功能。但是,有一点要注意的是,int的范围最大在 42亿的级别,如果你的真实业务量比较大,比如千万级的,可能用不了多久就会到上限,可以考虑使用 bigint。

2、当int到上限时,会发生什么?

当int到达上限后,再次进行自增插入,会提示重复错误 。

3、自增容易被撞数据,需要设置好权限验证。

例如:http://www.test.com/user/1  以及 http://www.test.com/user/2

3、资金字段的设计

在设计用户余额、钱包之类的业务设计中,由于都是资金字段,通常程序员喜欢用 decimal 元单位存储,在业界更佳实践是用分单位,在数据库中用100表示,对接过三方支付接口的人,能明显的发现无论是微信支付还是支付宝,都是用的分单位。

另外,在PHP对含有小数点的数据,判断相等或者其他操作的时候,需要小心。

在前端显示,做好显示转换即可

原因如下:

  • decimal是通过二进制实现的一种编码方式,计算效率不如整形高效。

  • 使用分存储,int可以 4200万级别的金额。bigint更能存储千兆级别的金额。

  • 定长存储,存储更紧凑,性能更好,减少碎片空间的出现。


对于基础不好的同学,建议报姜承尧老师在拉勾教育开的新课《姜承尧的MySQL实战宝典》,我也正在学,补补自己的短板。


姜承尧,是MySQL DBA界的老前辈,目前供职于腾讯,任金融数据平台与研发中心总监。


在久游开启了数据库职业生涯,接着在网易负责数据库内核、云数据库开发,现在腾讯负责金融支付系统的数据库开发。


这些年先后出版过 《MySQL技术内幕》《MySQL内核》 系列三本书,但相对理论,每本书的方向都较为专一,未能有效地从整个业务的全链路角度去分享一个互联网海量 MySQL 架构的实现。


跟我一起学习:



或者,选择学全场:




谢谢,下期再见~

文章转载自PHP Garden,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论