MySQL数值类型在binlog中需要注意的细节(r12笔记第69天)

MySQL里的数值类型分得很细,光整型数据就有多种数据类型。tinyint,smallint,mediumint,int(integer),还有范围最大的bigint,它们对应的数值范围也大大不同,大体来说就是下面的数值范围,从有符号数和无符号数来区别对待。

类型名称

有符号数(signed)

无符号数(Unsigned)

tinyint

-129~127

0~255

smallint

-32768~32767

0~65535

mediumint

-8388608~8388607

0~16777215

int(integer)

-2147483648~2147483647

0~4294967295

bigint

-9223372036854775808~9223372036854775807

0~18446744073709551615

这一点上Oracle做得很大气,直接一个number类型,精度也包了,两者在这个地方风格截然不同。

对于MySQL的数据类型,我们来说说bigint,如果按照无符号数,最大的值为18446744073709551615,这是一个相当大的数字,如果从有符号数据的角度来看就是-1,那么问题来了,在MySQL的binlog里面是否会区分signed还是unsigned呢,如果不区分,这类问题该怎么应对。

我做了如下的测试,使用conv来做进制转换。

> select conv(-1,10,2);
+------------------------------------------------------------------+
| conv(-1,10,2)                                                    |
+------------------------------------------------------------------+
| 1111111111111111111111111111111111111111111111111111111111111111 |
+------------------------------------------------------------------+

> select conv(18446744073709551615,10,2);
+------------------------------------------------------------------+
| conv(18446744073709551615,10,2)                                  |
+------------------------------------------------------------------+
| 1111111111111111111111111111111111111111111111111111111111111111 |
+------------------------------------------------------------------+

从机制转换的结果来看,两者是没有差别的,如果是实际的场景中,这可是天壤之别。

我们换一个角度来转换一下。

> select conv(repeat(1,64),2,-10);
+--------------------------+
| conv(repeat(1,64),2,-10) |
+--------------------------+
| -1                       |
+--------------------------+

> select conv(repeat(1,64),2,10);
+-------------------------+
| conv(repeat(1,64),2,10) |
+-------------------------+
| 18446744073709551615    |
+-------------------------+

这么看来,让人有些担忧,如果达到这种数据的临界点,会发生什么意料之外的结果呢。

我们来创建一个表,指定两个字段,一个为有符号类型,一个为无符号类型,然后对应的数字,从binlog来看看解析出来的结果。

create table t1 (id int unsigned not null auto_increment primary key, col1 bigint unsigned, col2 bigint signed) engine=innodb;

接着我们切一下日志,查看一下master对的状态,得到日志的偏移量和binlog名字。

> flush logs; show master status;
+---------------+----------+
| File          | Position |
+---------------+----------+
| binlog.000031 |      107 |
+---------------+----------+

这个时候我们插入两列值,一个无符号,一个有符号。

insert into t1 (col1, col2) values (18446744073709551615, -1);然后使用flush logs再次切换日志。

查看数据的情况,可以从输出看出两者是有明显的差别的。

> select * from t1;
+----+----------------------+------+
| id | col1                 | col2 |
+----+----------------------+------+
|  1 | 18446744073709551615 |   -1 |
+----+----------------------+------+

我们从binlog来解析一下。

mysqlbinlog -vv binlog.000031

得到的部分日志如下:

### INSERT INTO test.t1
### SET
###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
###   @2=-1 (18446744073709551615) /* LONGINT meta=0 nullable=1 is_null=0 */
###   @3=-1 (18446744073709551615) /* LONGINT meta=0 nullable=1 is_null=0 */
# at 268
#170519 18:54:47 server id 13386  end_log_pos 295       Xid = 76
COMMIT/*!*/;

这样看来对于binlog中,有符号数和无符号数都会按照无符号数来转换,当然直接看数据类型是没有标识有符号和无符号的差别的。所以如果是单纯要解析binlog处理数据就需要考虑到这个地方的差别,对此一种思路是查看information_schema中的列信息来做出更加明确的判断。

参考资料:https://mariadb.com/resources/blog/sign-row-based-binary-logging-and-integer-signedness-mysql-and-mariadb

原文发布于微信公众号 - 杨建荣的学习笔记(jianrong-notes)

原文发表时间:2017-05-19

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏与神兽党一起成长

根据xml配置校验bean

例子参考自官方文档,http://oval.sourceforge.net/u... 官方文档的xml配置有点过期了,一两个属性不合法。

16040
来自专栏orientlu

C 实现 哈夫曼编码

哈夫曼编码是一种用于数据压缩的无损熵编码,根据压缩数据符号出现频率大小进行编码, 出现频率越高,编码后占bit 越少的变长编码。(其他详细介绍见参考)

28130
来自专栏北京马哥教育

Awk是什么?一文带运维小白快速掌握Linux Awk用法

作者:a8 Awk、sed与grep,俗称Linux下的三剑客,它们之间有很多相似点,但是同样也各有各的特色,相似的地方是它们都可以匹配文本,其中sed和aw...

38860
来自专栏文渊之博

小议隐式转换引起的问题

隐式转换(Implicit conversion) ,这个情况每个程序员都或多或少的遇到过,这里我结合实际情况简单描述下常见的问题以及如何解决并阐述下原理。 所...

20290
来自专栏用户画像

JAVA反射机制

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对...

8610
来自专栏沈唁志

深入解析PHP中array_merge函数的用法

11220
来自专栏九彩拼盘的叨叨叨

JavaScript 数组练习题之实现

** 题 3:改变传入的数组,将数组中第 n(从 0 开始算 ) 个元素放到数组的开头 **

11010
来自专栏Jimoer

java设计模式之代理模式

代理模式 代理模式是常见设计模式的一种,代理模式的定义是:为其他对象提供一种代理以控制对这个对象的访问。 在某些情况下,一个对象不适合或者不能直接引用另一个对象...

33550
来自专栏菩提树下的杨过

[复习]The C Programming Language 2nd 习题集(1.1-1.10)

买不起iPhone4,只能弄了一台iTouch4,想尝试一下iOS上的开发,虽然有monoTouch可用,但是这东西要399美金授权,换成RMB好几千块了,算了...

23260
来自专栏C/C++基础

2018腾讯内部调岗面试试题1——使用C/C++但不能用sizeof判断操作系统是32位还是64位

2018上半年折腾了一回,想换个后台开发岗尝试锻炼一下自己,面了三个部门,将有关有意思的题目汇总记录下来,供大家参考。

11610

扫码关注云+社区

领取腾讯云代金券