可以参考下这篇文章,通过 trx id 进行过滤。
string 类型比较好看,是因为存储层记录的就是对应 string 的 ascii 码,例如您截图里 cstr 那里的 hex 值就直接是 ascii 码。
不同于 string 类型,decimal 类型在 ob 内部是通过 ObNumber 来实现的,这是个相对比较复杂的结构体,所以这里没有展示这个结构体里的具体内容。
有兴趣的话可以参照下源码中的 ob_number_v2.h,它是用结构体 ObCompactNumber 来记录 decimal 类型的数据的,用一个 4 字节的 ObNumberDesc 来描述这个 decimal 的特征,和一个 uint32_t 的 digits_ 数组来存储 decimal 的数值。
例如你这 12 个字节的 decimal 就可以分成两部分(这部分对原理不感兴趣的话可以忽略~):
- 第一部分是 4 个字节的 ObNumberDesc 02 00 00 c0,02 表示 len,说明后面的数组会用两个 uint32_t 来表示这个 decimal,中间两个 00 和 00 分表是保留位和 flag,先忽略,最后那个 c0 代表指数位的信息,例如数组中第一个 uint32_t 是 A,第二个是 B,那么这个 decimal 的值就是 A * (10^(9 * (c0 - c0)) + B * (10^(9 * (c0 - c0 - 1)) = A + B * (10^-9);
- 第二部分是 8 个字节的两个 uint32_t A 和 B。
您可以把 hex 分成三段,每段四个字节,用后面两段算一下 A +(B 乘以 10 的 -9 次方)的值,看看这个值是不是和您的 decimal 值相同。
我算出来这个值等于 0x0A + 0x055D4A80 *(10^-9),应该是 10.09。
验算一下应该也是对的。
by the way:
我们上半年已经完成了对 decimal 类型实现方式的一次重构,会在下一个版本 4.3 中带上。到时候 decimal 类型在 ob 内部不再会是上面您看到的这种复杂的数据结构,而是宽整形 wide integer。举个例子:比如一个列的数据类型是 decimal(4, 2),精度 precision 是 4,小数点后的有效位数 scale 是 2,那么这个列中的 10.09 会直接存储为一个 int8,值为 1009,展示时只需要根据列的元信息中的 scale 决定在哪里点个小数点儿即可,内部计算时只需要让两个 wide integer 的小数点儿对齐,然后当做整数进行计算即可。4.3 版本的 decimal 类型再配合上列存,计算和存储都会得到很大的优化~
不好意思,没看懂0A和055D4A80是怎么取出来的
不好意思,我没说清楚,你那一串十六进制数是 02 00 00 C0 0A 00 00 00 80 4A 5D 05,分成 3 个 uint32 之后就是:
02 00 00 C0 → len = 2, se = 0xC0
0A 00 00 00 → digits[0] = 00 00 00 0A
80 4A 5D 05 → digits[1] = 05 5D 4A 80
这个信息的展示和 decimal 的内部实现相关。下一个 ob 4.3 版本,10.09 展示出来应该会是 1009,到时候就好看很多了
如果展示出1009,到时候再确定小数点位置就可以了吧,那这个位置要怎么查呢
哈哈,你直接 show create table 看下这个列的数据类型就知道了~
比如看到 decimal(4, 2),4 表示有效数字位数,2 表示小数点儿后的有效数字位数,1009 从右边数两位点个小数点儿就变成了 10.09~
对了,4.3版本的clog格式相比于4.1和4.2变化大吗
clog 应该没啥变化,我只知道 decimal 类型在实现上变化巨大~
哈哈,这个应该也和 date 的实现相关,我不太了解 date 这个数据类型,也得翻下 OB 开源出来的代码了~
看了眼代码,date 在 ob 里是用一个整型记录的,记录的是离 1970-01-01 有多少天,所以应该是把 0X384B 先转成十进制 14411,然后再用 1970-01-01 加上这个天数得到 date 表示的日期,而且还需要考虑闰年啥的。
如果数学不好,不想自己算的话,就直接问下 chatgpt 吧~
可是我date列不是1999年7月12日
我插的那个值是2022-09-21
看来不能完全相信 chatgpt 啊,0X4B38 = 19256,还是得自己拿 date_add 算一把……
没事了,gpt的答案有些问题
再也不偷懒问 gpt 了
加入有问必答板块。