Подтвердить что ты не робот

Можно ли сохранить 1-байтовый номер в Postgres?

У меня есть 7 8-битных целочисленных значений для записи, которые я хочу сохранить в Postgres. Pg не предлагает одиночный байтовый целочисленный тип, SMALLINT или 2 байта, являющийся наименьшим целым типом данных. Есть ли в любом случае я могу хранить 7 8-битных чисел и экономить место?

Будет ли тип массива с массивом из 7 элементов более компактным? Или я должен сделать двоичное представление моих 7 чисел (например, используя пакет в Perl) и сохранить это в одном байтовом поле?

Любые другие предложения?

4b9b3361

Ответ 1

Учитывая, что накладные расходы для любой строки в PostgreSQL 23 байта (HeapTupleHeaderData), если вы действительно заботитесь о небольших объемах пространства, Вероятно, вы выбрали неправильный способ хранения ваших данных.

Независимо от того, что все более сложные типы имеют свои собственные накладные расходы (bytea добавляет четыре байта служебных данных, например, бит-строки с 5 по 8), единственный способ выполнить то, что вы ищете, - использовать bigint (8 байты), числовое смещение каждого значения и объединение результата. Вы можете сделать это, используя операции битовые строки, чтобы сделать код более простым - вычислить как битовую строку, а затем передать в bigint перед сохранением - или просто вручную умножить/добавить, если вы хотите, чтобы скорость была лучше. Например, здесь, как вы складываете два байта вместе в структуру двух байтов, а затем возвращаете их обратно:

int2 = 256 * byte1 + byte2
byte1 = int2 / 256
byte2 = int2 % 256

Вы можете расширить ту же идею, сохранив 7 из них. Накладные расходы на поиск все еще будут ужасными, но вы фактически сохранили некоторое пространство в этом процессе. Но не так много относительно только заголовка строки.

Ответ 2

Существует pg_catalog.char (другое обозначение - "char" ), в котором используется только 1 байт, чтобы сохранить его значение.

select pg_column_size( 'A' );
pg_column_size
----------------
              2
(1 row)

select pg_column_size( 'A'::"char" );
pg_column_size
----------------
              1
(1 row)

Ответ 3

Будете ли вы когда-либо искать записи, используя эти значения?

Если да - используйте обычные типы данных, такие как int4 (или даже int8, если вы используете 64-битную архитектуру).

Если нет - сначала спросите себя - какая точка хранения этих значений в Pg? Вы можете использовать bytea (сложный i/o) или битстроны (еще более сложный i/o), но в чем смысл? Сколько миллиардов записей у вас будет? Вы действительно проверяли, что меньший тип данных использует меньше места (подсказка: это не так, проверьте это - есть проблемы с выравниванием данных)? Вы работаете под впечатлением, что меньший тип данных работает быстрее (это не так. На самом деле сложнее сравнивать два значения int2, чем два значения int4 в 32-битной архитектуре).

Ответ 5

Сначала вы спросили около 7, но теперь 6 байт. Шесть 8-битных значений точно соответствуют размеру MAC-адреса и построению PostgreSQL типа macaddr. Вы можете вставить эти байты, используя синтаксис MAC f.i. А1-В2-С3-Д4-Е5-F6.

Ответ 6

Я сам их не тестировал, но для этого есть расширения; например http://pgxn.org/dist/tinyint/.