Типы данных.md 4.4 KB

Типы данных помогают нам поддерживать целостность данных. Например, если мы тип колонки укажем как целое число, то вставить туда строку «тыща» не получится:

create temp table book_tmp(name text, pages int);
-- ok
insert into book_tmp (name, pages) values ('Python к вершинам мастерства', '898');
-- error
insert into book_tmp (name, pages) values ('Python к вершинам мастерства', 'тыща');

И благодаря этому наши данные будут целостными.

Плюс в зависимости от используемого типа можно настраивать дополнительные ограничения, поддерживающие целостность данных, например, у книги не может быть отрицательного или нулевого количества страниц:

drop table book_tmp;
create temp table book_tmp(name text, pages int check (pages>=1));
-- error
insert into book_tmp (name, pages) values ('Python к вершинам мастерства', -898);

Теперь не получится сохранить книгу с отрицательным количеством страниц. Для типа данных строка или дата такого ограничения выставить не удастся, но для этих типов можно устанавливать свои ограничения, на длину строки или на допустимый диапазон дат, например.

Помимо целостности и предоставления разных возможностей типы данных служат оптимизации хранения. Скажем, как мы можем сохранить значение 333? В виде разных типов чисел и в виде разных типов строк. Давайте посмотрим, сколько байт займет это значение для разных типов данных.

Мы можем использовать два двоеточия для приведения типов друг к другу, то есть чтобы значение одного типа привести к другому типу, когда это возможно. А встроенная в PostgreSQL функция pg_column_size возвращает размер в байтах, который займёт указанное значение конкретного типа.

SELECT pg_column_size('333'::text); -- 7
SELECT pg_column_size('333'::varchar(3)); -- 7
SELECT pg_column_size('333'::char(3)); -- 7

SELECT pg_column_size('333'::char(255)); -- 259

SELECT pg_column_size(333::bigint); -- 8
SELECT pg_column_size(333::int);  -- 4
SELECT pg_column_size(333::smallint);  -- 2

SELECT pg_column_size(333::numeric(3)); -- 8

Мы видим, что одно и то же значение может занимать в базе данных как 2 байта, так и 259 байт. В мире книг около 130 миллионов всего. Если мы храним 2 байта по каждой книге, то получаем 260 мегабайт займёт эта колонка на диске.

Если вместо 2 байт по каждой книге храним 259 байт, то для 130 млн книг это уже около 33 гигабайт.

То есть, храня эти данные правильно, мы экономим на диске 32 с хвостиком гигабайта. Если эта колонка будет еще в индексе где-то участвовать, то ещё больше места мы сэкономим, потому что информация в индексе дублирует информацию в основной таблице для ускорения поиска.

Ну и помимо оптимизации хранения мы также получаем оптимизацию производительности, потому что меньше данных нам надо считывать с диска и так далее. Считать 260 мегабайт значительно быстрее, чем 33 гигабайта.