PostGIS
切换暗/亮/自动模式 - PostGIS 空间数据库 切换暗/亮/自动模式 - PostGIS 空间数据库 切换暗/亮/自动模式 - PostGIS 空间数据库 返回主页 - PostGIS 空间数据库

RFC-2:对齐思路

进入对齐

  • 目标 1:让我们的磁盘格式对齐,以便在将磁盘格式载入内存后,我们可以直接从中读取。
  • 目标 2:尽可能少地牺牲当前方案的紧凑性
  • 目标 3:保留表示 GEOMETRYCOLLECTION(GEOMETRYCOLLECTION(…)) 等结构的能力

PG_LWGEOM/LWGEOM

目前,PG_LWGEOM 只是 LWGEOM,前面附加了 4 个字节的额外信息。CREATE TYPE 中的“align”关键字保证对整个 PG 结构进行对齐,因此可以保证 PG_LWGEOM 的前面处于对齐边界上。这意味着 LWGEOM 的前面将偏离边界四个字节。

最简单的修复方法是让我们的 LWGEOM/PG_LWGEOM 成为相同的结构,并让 LWGEOM 携带 PG_LWGEOM 的“大小”属性,即使内部没有使用它。它可以是“应用程序数据”,大多数情况下应用程序是 PostgreSQL。

由于我们的主要目标是保持磁盘空间占用量,因此增加 liblwgeom 的非 PostgreSQL 应用程序的内存占用量似乎是一个合理的权衡。

TYPE

序列化形式开头处的类型字符存在问题。通过将其扩展到 2 个字节,并与一些 2 个字节长度字段结合使用,我们可以以仅增加 1 个字节为代价实现对齐。请参阅 SRID 中的以下方法,该方法将类型和 srid 结合起来以将成本降低到 1 个字节。

BBOX

由于 bbox 是 4 个浮点数(= 2 个双精度数)宽,因此我们可以忽略它。它是否可选不是问题,添加或删除它不会改变任何内容的对齐方式。

SRID

目前,SRID 是可选的,为 4 个字节。这是一个问题,因为它会根据 SRID 的存在使我们进入/退出对齐状态。我看到两种方法

– 使其更小且强制使用。

o 将其减少到 2 个字节,并将类型字节扩展到 2 个字节,然后您将获得一个 4 个字节的块,可以轻松添加到另一个 4 个字节的块中以实现对齐。o 将其减少到 3 个字节,并将类型字符中的备用位用于额外的几何类型。

目前,EPSG 数据库中没有 SRID 值超过 32000,因此它们适合无符号短整型(65536)。使用三个字节,SRID 可以大到 16M。但是,用户已经用天知道什么填充了他们的 spatial_ref_sys 表。

– 将其变大并保持可选。

将 SRID 加倍到 8 字节使其成为无痛可选字段,如 bbox,但以 4 字节为代价。但是,由于生产中的大多数几何体确实携带 SRID 信息,因此这是一个可能适用于许多用户的尺寸命中。

长度

长度(纵坐标数组长度、环计数、子对象计数)是最难处理的。它们是 4 字节长,并且大部分一次出现一个,这会产生每次遇到一个时都会使结构错位的效果。

  • 基本修复,只需将所有长度填充到 8 字节。
  • 更复杂的修复,移动到更像 shape 文件的序列化形式,它将所有偏移量存储在前面的一个块中,然后将所有双精度值存储在一个不间断的集合中。这意味着给定偏移量组的净对齐不足最多只有四个字节。

完全填充的示例

最简单的方法是根据需要填充所有内容。以下是某些示例的外观。正如预期的那样,最精简的要素(2d 点、两顶点的 2d 线)受到的打击最大。不幸的是,从对齐访问获得的速度提升与磁盘 I/O 损失之间的平衡需要一些经验测试。

:: POINT2D :

Pg VarSize 类型 srid X Y

旧大小:25 字节 新大小:32 字节(大 28%)

:: LINESTRING2D(带边界框和 srid):

Pg VarSize 类型 srid 边界框最小值 边界框最大值 点数 X0 Y0 X1 Y1

旧大小:61 字节,新大小:72 字节(大 18%)

:: POLYGON2D(带边界框和 srid):

Pg VarSize 类型 srid 边界框最小值 边界框最大值 环数 点数 X0 Y0 X1 Y1 X2 Y2 X3 Y3

旧大小:97 字节,新大小:112 字节(大 15%)

:: MULTILINESTRING2D(带边界框和 srid,仅一部分):

请注意,边界框和 srid 已从子几何中删除。

Pg VarSize 类型 srid 边界框最小值 边界框最大值 线数 Pg VarSize 类型 点数 X0 Y0 X1 Y1

旧大小:66 字节,新大小:88 字节(大 33%)

压缩头示例

将“类型”保持为 8 位,并将“srid”缩减为 24 位,可将元数据复杂性压缩到一个 32 位空间中。由于 SRID 是强制性的,因此在“类型”中也可以释放一位以用于更多几何类型。

:: POINT2D :

Pg VarSize 类型/srid X Y

旧大小:25 字节,新大小:24 字节(小 4%)

:: LINESTRING2D(带边界框和 srid):

Pg VarSize 类型/srid 边界框最小值 边界框最大值 点数 X0 Y0 X1 Y1

旧大小:61 字节,新大小:64 字节(大 5%)

:: POLYGON2D(带边界框和 srid):

Pg VarSize 类型/srid 边界框最小值 边界框最大值 环数 点数 X0 Y0 X1 Y1 X2 Y2 X3 Y3

旧大小:97 字节 新大小:104 字节(大 7%)

:: MULTILINESTRING2D(带边界框和 srid,仅一部分):

请注意,边界框和 srid 已从子几何中删除。

Pg VarSize 类型 / srid 边界框最小值 边界框最大值 nlines Pg VarSize 类型 / srid npoints X0 Y0 X1 Y1

旧大小:66 字节 新大小:80 字节(大 21%)