我想知道在postgresql表中计算最大列数的正确方法。他们的网站上说:
每个表的最大列数为250-1600,取决于列类型。
因此,根据列类型,我如何确定最大列数?
每个表的最大列数为250-1600,取决于列类型。
因此,根据列类型,我如何确定最大列数?
页面布局
。PageHeader
的开销,在当前的PostgreSQL版本中它是24个字节。因此,我们只剩下8168字节。但是……还有一个指针数组ItemIdData
。假设这个页面只有1条记录,因此这个条目只占用4个字节(1个条目)。因此,我们只剩下8164字节。但是……每个记录还有一个RecordHeader
,占用23个字节。因此,我们只剩下8141个字节。但是……在RecordHeader
后面还有一个NULL
位图,但假设我们已经定义了所有列都具有NOT NULL
约束条件,因此这里仍然是8141个字节。但是……还有一个叫做MAXALIGN
的东西。看看Erwin提供的这个精彩答案。我们在这里讲述的是24+4+23=51
的偏移量。现在一切都取决于您系统上这个参数的值。如果它是32位的,则偏移量将对齐到52,这意味着我们会浪费一个字节。如果它是64位的,则偏移量将对齐到54,这意味着我们会浪费3个字节。我的系统是64位的,因此我认为我们只剩下8138个字节。MAXALIGN
)。让我们为所有列选择int2
。简单的计算表明,我们应该能够挤入4069个这种类型的列:所有列都是NOT NULL
并且相同类型。echo "CREATE TABLE tab4069 (" > tab4069.sql
for num in $(seq -f "%04g" 1 4069); do
echo " col$num int2 not null," >> tab4069.sql; done
echo " PRIMARY KEY (col0001) );" >> tab4069.sql
然而,如果您尝试创建此表格,将会遇到以下错误:
错误:表格最多只能有1600列
通过一些搜索,我们找到了类似问题,并查看了PostgreSQL的源代码,我们得到了答案(第23至47行):
/*
* MaxTupleAttributeNumber limits the number of (user) columns in a tuple.
* The key limit on this value is that the size of the fixed overhead for
* a tuple, plus the size of the null-values bitmap (at 1 bit per column),
* plus MAXALIGN alignment, must fit into t_hoff which is uint8. On most
* machines the upper limit without making t_hoff wider would be a little
* over 1700. We use round numbers here and for MaxHeapAttributeNumber
* so that alterations in HeapTupleHeaderData layout won't change the
* supported max number of columns.
*/
#define MaxTupleAttributeNumber 1664 /* 8 * 208 */
/*
* MaxHeapAttributeNumber limits the number of (user) columns in a table.
* This should be somewhat less than MaxTupleAttributeNumber. It must be
* at least one less, else we will fail to do UPDATEs on a maximal-width
* table (because UPDATE has to form working tuples that include CTID).
* In practice we want some additional daylight so that we can gracefully
* support operations that add hidden "resjunk" columns, for example
* SELECT * FROM wide_table ORDER BY foo, bar, baz.
* In any case, depending on column data types you will likely be running
* into the disk-block-based limit on overall tuple size if you have more
* than a thousand or so columns. TOAST won't help.
*/
#define MaxHeapAttributeNumber 1600 /* 8 * 200 */
pg_column_size()
函数对于任何类型的输出,特别是对于复杂类型,如数组、hstore
或jsonb
。