2014-10-05 3 views
6

Я хотел бы знать, что является правильным способом вычисления максимального количества столбцов в таблице postgresql. На их веб-сайте написано:Как вычислить максимальные столбцы в Postgresql

Maximum Columns per Table 250 - 1600 depending on column types

Так, в зависимости от типа столбца, как определить максимальные столбцы?

+0

@ Ответ vyegorov дает технические детали довольно хорошо. Хотелось бы отметить, однако, что если вы беспокоитесь о том, чтобы набрать ограничение на количество столбцов, у вас, вероятно, есть некоторые проблемы с дизайном в вашей схеме. Даже 250 столбцов должны быть очень редкими в правильно нормированной схеме. (Pg может обрабатывать больше, чем диапазон 250-1600 cols для динамически созданных наборов результатов, это только на диске, ограниченное этим значением.) –

ответ

8

Вам необходимо заглянуть в детали хранения физических данных PostgreSQL, под-Page Layout.

  1. Как вы знаете, размер блока PostgreSQL по умолчанию составляет 8kB (8192 байта). Вы также должны знать, что строки в PostgreSQL не могут охватывать границу блока. Это уже дает вам ограничение по размеру 8192 байта. Но ...

  2. Глядя на вышеуказанный макет страницы, есть также накладные расходы для PageHeader, что составляет 24 байта в текущей версии PostgreSQL. Итак, у нас осталось 8168 байт. Но ...

  3. Существует также ItemIdData, который представляет собой массив указателей. Предположим, что на этой странице есть только 1 запись, поэтому эта запись занимает всего 4 байта (1 запись). Итак, осталось 8164 байт. Но ...

  4. Каждая запись также имеет RecordHeader, которая, как известно, занимает 23 байта. Итак, у нас осталось 8141 байт. Но ...

  5. Там также NULL -bitmap сразу после RecordHeader, но давайте предположим, что мы определили все наши столбцы с NOT NULL ограничения. Итак, те же 8141 байт. Но ...

  6. Есть такая вещь - MAXALIGN. Посмотрите at this wonderful answer by 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 

Тем не менее, если вы будете пытаться создать эту таблицу, вы попали ошибку:

ERROR: tables can have at most 1600 columns

Немного поиска точки к the similar question и, глядя в the sources of the 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 */ 

Существует много типов переменной длины, и они выполняют фиксированные накладные расходы 1 или 4 байта + некоторое количество байтов в фактическом значении. Это означает, что вы никогда не узнаете заранее, сколько места займет запись, пока вы не приобретете фактическое значение. Разумеется, эти значения могут храниться отдельно через the TOAST, но, как правило, более крупные (всего 2 КБ общей длины).

Просьба обратиться к official docs on types, чтобы узнать место, используемое для типов фиксированной длины. Вы также можете проверить вывод функции pg_column_size() для любого типа, особенно для сложных, например массивов, hstore или jsonb.

Вам нужно будет углубиться в более подробную информацию, если вы хотите получить более полное видение этой темы.

+0

Существует также проблема классов хранения, с которыми приходится иметь дело при рассмотрении того, какие столбцы TOUSTable. –

+0

Wow .. очень информативный. Тем не менее, я должен получить скорость на технологии postgresql, прежде чем я смогу понять все, что вы написали. – Luke101

Смежные вопросы