java postgresql 数据类型_PostgreSQL text类型短数据存储说明

今天在查看数据库数据文件时,进行一下操作:

CREATE TABLE test ( id int, info text );

INSERT INTO test VALUES (1, ‘abc’), (2, ‘def’);

然后通过hexdump查看数据:

0000000 0000 0000 0140 016f 0000 0000 0020 1fc0

0000010 2000 2004 0000 0000 9fe0 0040 9fc0 0040

0000020 0000 0000 0000 0000 0000 0000 0000 0000

*

0001fc0 023f 0000 0000 0000 0000 0000 0000 0000

0001fd0 0002 0002 0802 0018 0002 0000 6409 6665

0001fe0 023f 0000 0000 0000 0000 0000 0000 0000

0001ff0 0001 0002 0802 0018 0001 0000 6109 6362

0002000

发现text类型中的abc和def在数据文件表示为 09616263和09646566,查看代码可知text类型其实为varlena,他的结构为:

struct varlena

{

charvl_len_[4];/* Do not touch this field directly! */

charvl_dat[1];

};

前四个字节为长度标识,在这里只有一个字节,而且3个字符的长度为9,百思不得其解啊,遂进行调查,发现,这是因为插入数据较短,数据库给优化了,将原来长度为4个字节的标识为变成了1个:

else if (VARLENA_ATT_IS_PACKABLE(att[i]) &&

VARATT_CAN_MAKE_SHORT(val))

{

/* convert to short varlena -- no alignment */

data_length = VARATT_CONVERTED_SHORT_SIZE(val);

SET_VARSIZE_SHORT(data, data_length);

memcpy(data + 1, VARDATA(val), data_length - 1);

}

这里主要是由于SET_VARSIZE_SHORT起的作用:

#define SET_VARSIZE_SHORT(PTR, len) SET_VARSIZE_1B(PTR, len)

#ifdef WORDS_BIGENDIAN

#define SET_VARSIZE_1B(PTR,len) \

(((varattrib_1b *) (PTR))->va_header = (len) | 0x80)

#else

#define SET_VARSIZE_1B(PTR,len) \

(((varattrib_1b *) (PTR))->va_header = (((uint8) (len)) << 1) | 0x01)

so, 考虑到‘\0’占位情况,即3+1=4,4 << 1 = 8, 8 | 0x01 = 9,于是这里便是9。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值