Postgresql:文本/ varchar的行内与行外

RvP*_*vPr 5 sql database postgresql varchar text

两部分问题:

  1. Postgresql在行内或行外存储文本/ varchars的行为是什么?我是否认为默认设置将所有列始终存储在行中,直到达到2kB大小?

  2. 我们可以控制上述行为吗?有什么方法可以更改特定列/表的阈值,或者强制特定列始终存储在行外?

我已经阅读了PostGresql Toast文档(http://www.postgresql.org/docs/8.3/static/storage-toast.html),但是我看不到任何更改阈值的选项(默认值似乎是2kB -for-row)或强制列始终存储行外(EXTERNAL仅允许它,但不强制执行)。

我已经找到了说明如何在SQL Server上执行此操作的文档(https://msdn.microsoft.com/zh-cn/library/ms173530.aspx),但没有看到与PostGresql类似的内容。


如果有人对我的动机感兴趣,那么我有一个表,该表包含短一致性列(ID,时间戳等),一个列为varchar(200)和一个列为text / varchar(max)的表,长度非常大。我目前将两个varchars存储在单独的表中,只是为了允许在短一致性列上进行有效的存储/查找/扫描。

但是,这很痛苦,因为我经常需要进行联接才能读取所有数据。我真的很想将上述所有字段存储在同一张表中,并告诉Postgresql始终强制将2个VARCHARs行外存储。

Ren*_*nzo 7

编辑答案

对于问题的第一部分:您是对的(例如参见this)。

对于问题的第二部分:存储列的标准方法是压缩大小超过 2KB 的可变长度文本字段,并最终将它们存储到一个单独的区域,称为“TOAST 表”。

您可以通过对列使用以下命令向系统提供有关如何存储字段的“提示”:

ALTER TABLE YourTable
  ALTER COLUMN YourColumn SET STORAGE (PLAIN | EXTENDED | EXTERNAL | MAIN)
Run Code Online (Sandbox Code Playgroud)

手册

SET STORAGE

此表单设置列的存储模式。这控制此列是内联保存还是保存在辅助 TOAST 表中,以及是否应压缩数据。PLAIN必须用于固定长度的值,例如整数,并且是内联的、未压缩的。MAIN用于内联、可压缩数据。EXTERNAL用于外部未压缩数据,EXTENDED用于外部压缩数据。EXTENDED是大多数支持非 PLAIN 存储的数据类型的默认值。使用 ofEXTERNAL将使对非常大的文本和 bytea 值的子字符串操作运行得更快,但会增加存储空间。请注意,SET STORAGE它本身不会更改表中的任何内容,它只是设置在未来表更新期间要采用的策略。有关更多信息,请参阅第 59.2 节。

由于手册在这一点上没有完全明确,这是我的解释:在任何情况下,关于如何存储字段的最终决定都留给系统,考虑到以下约束:

  1. 不能存储任何字段以使行的总大小超过 8KB
  2. 如果字段的大小小于 TOAST_TUPLE_THRESHOLD
  3. 在满足前面的约束后,系统会尝试满足SET STORAGE用户指定的策略。如果未指定存储策略,则自动声明每个 TOAST-able 字段EXTENDED

在这些假设下,确保列的所有值都存储在行外的唯一方法是使用TOAST_TUPLE_THRESHOLD小于列的任何值的最小大小的值重新编译系统。