美文网首页
使用bytea的hex格式减小表占用的空间大小

使用bytea的hex格式减小表占用的空间大小

作者: twistzhuo | 来源:发表于2018-03-11 16:52 被阅读0次

    背景

        随着数据量的不断增大,生产环境db集群的存储空间面临着比较大的压力,经过团队的讨论之后,决定把优化方向指向bytea的十六进制格式存储。生产环境中表的敏感字段会先通过sha256加密,这部分数据通过bytea的十六进制格式存储可以节省下不少的空间。

    面临的问题

    虽然看起来只是使用了postgres中的一种基本类型,但是在实施过程中却发现不是那么简单。在生产环境中,还需要考虑一个可靠性和稳定性的问题。下面做一个简单的回顾。

    问题1:

        要使用bytea的hex格式存储数据,需要先使用字符串函数decode(target_column_value,'hex')进行解码,否则系统会做varchar到bytea类型的强制转换,达不到节省空间的目的。

        生产环境中存在大量的表是离线导入的(使用pgloader从文件中导入),这部分表按月更新。如果是仅仅修改varchar类型为bytea类型的话,在使用pgloader导入数据时,便会遇到上述的问题。

    问题2:

        在现有架构中,业务方所有对db的访问都通过数据库访问中间件(导师的作品,名为ditto)来进行统一控制,而ditto的性能开销主要在cpu这一块,增加hex格式的编码和解码这一环节明显会增大ditto的压力。

    方案

    方案1    通过脚本修改数据文件 + udf

        解决问题1:

        创建两张字段类型不同的表(表A的字段类型为varchar,表B的字段类型为bytea)

    表B 表A

        往两张表中插入相同的数据(表B做decode处理),再将两张表的结果copy出来,进行比对,发现表B的目标字段和表A的差别在于表B的目标字段前多了\x。对数据文件进行处理,再使用pgloader将数据分别导入表A表B,结果

    占用空间的大小

        可以看出空间明显降低,64*(23+1+1+32+8+8)/(23+1+1+64+8+8) 约等于46,符合预期结果。

        解决问题2:

        db集群目前的主要压力在于io,cpu的使用率一直都维持在一个极低的水平。因此,在db层面使用udf来解决insert和select 时数据类型的转换,是一个比较好的选择。相比使用触发器来解决该问题会更加简单,不需要为每个表都定制化触发器,相比使用hook技术也会更加安全可靠。

    方案2    通过create type创建一个新类型(待验证)

        postgres支持用户创建一个新的类型。通过自定义输入输出函数(c或其他底层语言编写)以输入函数中将varchar类型转换为bytea的hex格式,在输出函数中将bytea的hex格式转换为varchar格式。

    相关文章

      网友评论

          本文标题:使用bytea的hex格式减小表占用的空间大小

          本文链接:https://www.haomeiwen.com/subject/pohwfftx.html