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

~={yellow}Символьные типы данных=~

~={yellow}Численные типы данных=~

--- целые
smallint: значения от -32768 до 32767 (2 байта)
int: значения от -2 147 483 648 до 2 147 483 647 (4 байта)
bigint: значения от -9 223 372 036 854 775 808 до 9 223 372 036 854 775 807 (8 байт)

--- нецелые
real: 4 байта
double precision: 8 байт

--- для точный вычисленией
numeric(10, 2):
-- где 10 - точность - это общее количество знаков, которые могут быть сохранены, включая знаки после запятой
-- 2 - масштаб - это максимальное количество знаков после запятой

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

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 гигабайта.

~={yellow}Перечисления=~

create type day_of_week as enum (
	'понедельник',
	'вторник',
	...
)

-- Создаем таблицу с полем типа day_of_week
create table advertiser_support_work_time (
    day_of_week day_of_week primary key,
    start_time time not null,
    end_time time not null
);

-- Вставляем данные
insert into advertiser_support_work_time (day_of_week, start_time, end_time) values
    ('понедельник', '09:00:00', '19:00:00'),
    ('вторник', '09:00:00', '19:00:00'),
    ('среда', '09:00:00', '19:00:00'),
    ('четверг', '09:00:00', '19:00:00'),
    ('пятница', '09:00:00', '19:00:00'),
    ('суббота', '10:00:00', '19:00:00'),
    ('воскресенье', '10:00:00', '19:00:00');

select * from advertiser_support_work_time;
-- Создание таблицы с помощью проверки check
create table color (
	name varchar(22) primary key check(name in (
		'адовый красный',
		'ядрёный зелёный',
		'подозрительная мурена'
	))
);