我正在使用postgresql hstore扩展并且很好奇数据是如何在内部存储的。请指出我在hstore源代码中查看的位置以查看实现细节。
答案 0 :(得分:8)
hstore
是主要PostgreSQL发行版的一部分,它位于http://git.postgresql.org/和GitHub上。 Here is hstore
in git head
它看起来像存储为varlena,这意味着它像任何其他东西一样是TOASTable。缺点是需要从磁盘读取整个字段 - 至少如果它是压缩的 - 以提取密钥。
这也意味着,与任何其他正常字段值一样,更新字段的任何部分都要求必须将整个元组(行)的新副本写入表并标记旧的副本当任何活动交易不再可见时到期(请参阅Pg手册中的MVCC)。因此,对于经常更改的数据,大hstore
是不可取的,因为每当它的任何部分发生变化时,您都需要重写整个事物(以及包含它的行)。
这些来源似乎没有太多的评论方式,以提供hstore值的结构和存储方式的概述,并且它可以快速进入一些宏观森林。
答案 1 :(得分:3)
存储本身并不令人惊讶。
有趣的部分是如何编制索引以便能够有效地回答诸如
之类的查询从planet_osm_line中选择osm_id,name,tags,其中'frequency => 16.7,铁路=> “rail”'< @ tags;
(这是一个真实的例子)意思是:“找到(hstore)字段”包含“映射频率=> 16.7和铁路=>轨道的所有记录。
CAVEAT:这只是来自记忆。
有两个组成部分:
首先是GiST index,它可以看作是一种“草率的B树”,它有时并不能准确地告诉你要采取哪个分支,而是给你一些分支。 PostgreSQL将它用于几何索引之类的东西(例如,你可以查询一个点是否在多边形中)。索引并没有给你一个完美的打击,但可能会大大减少搜索空间。
其次,有一个“哈希”(对于你的Perlists)/“词典”(对于你的Python教徒)的编码来利用GiST:你将每个键和哈希的每个键/值对散列成一个小的int (细节是模糊的,但我们假设0..255),取一个这样大小的位域,并为你得到的每一个哈希值在你的位域中戳一个洞(我认为Knuth有一个很好的例子,索引卡有开/它们的边缘和织针上都是封闭的孔 - 是的,here it is。
然后你只要嫁给那两个人。 AFAIR Oleg Bartunov和Theodor Tsigaev提出了这个问题。我第一次看到它时,我的头部爆炸了。