Storing data as a uint64 provides a net storage savings for most data. For example, unlike normal 64 bit binary encoding, values between 0 and 127 consume only one byte of storage on disk.
Simple usage:
CREATE EXTENSION varint; -- Create a table CREATE TABLE t ( i VARINT64, -- Signed INT8 u VARUINT64, -- Unsigned INT8 ); -- Check the sizes in memory test=# SELECT pg_column_size('0'::VARINT64), pg_column_size('0'::VARUINT64); pg_column_size | pg_column_size -----------------+----------------- 5 | 5 (1 row) test=# INSERT INTO t VALUES (0::VARINT64, 0::VARUINT64); test=# SELECT pg_column_size(i) AS signed, pg_column_size(u) AS unsigned FROM t; signed | unsigned --------+---------- 2 | 2 (1 row)
For values between 0
and 562,949,953,421,311
(0x1ffffffffffff
, a.k.a. 249 -
1), uint64
will save anywhere between 1-7 bytes of storage.
For values between 562,949,953,421,312
(0x2000000000000
, a.k.a. 249)
and 72,057,594,037,927,935
(0xffffffffffffff
,
a.k.a. 256 - 1) the space savings is a wash.
For values greater than 72,057,594,037,927,936
(0x100000000000000
, 256) and less than 264
- 1, the space savings costs an extra 1-2 bytes.
Bytes Consumed | Minimum Value | Maximum Value |
---|---|---|
1 byte | 0 | 127 |
2 bytes | 128 | 16383 |
3 bytes | 16384 | 2097151 |
4 bytes | 2097152 | 268435455 |
5 bytes | 268435456 | 34359738367 |
6 bytes | 34359738368 | 4398046511103 |
7 bytes | 4398046511104 | 562949953421311 |
8 bytes | 562949953421312 | 72057594037927935 |
9 bytes | 72057594037927936 | 9223372036854775807 |
10 bytes | 9223372036854775808 | 18446744073709551615 |
For most people, there is probably a large net savings for on-disk storage as a result of using varint encoding.
NOTE: The space savings and encoding mentioned above excludes the space overhead from PostgreSQL's VARLENA representation.
For additional information about varint encoding, see Google's Protobuf encoding documentation.