Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / PostgreSQL Новый топик    Ответить
 character types: невнятная справка...  [new]
Cyrax_02
Member

Откуда:
Сообщений: 1396
https://www.postgresql.org/docs/current/datatype-character.html
The storage requirement for a short string (up to 126 bytes) is 1 byte plus the actual string, which includes the space padding in the case of character. Longer strings have 4 bytes of overhead instead of 1...

There is no performance difference among these three types, apart from increased storage space when using the blank-padded type, and a few extra CPU cycles to check the length when storing into a length-constrained column. While character(n) has performance advantages in some other database systems, there is no such advantage in PostgreSQL; in fact character(n) is usually the slowest of the three because of its additional storage costs. In most situations text or character varying should be used instead.
Непонятно следующее:
1) 126 байт включительно или невключительно ?
2) требуется 1 байт дополнительной памяти для любых строк с типом varchar(N) / char(N), где N до 126
или для строк типа char(N) / varchar(N) / text с фактической длиной до 126 байт ?
3) "because of its additional storage costs" - это касается только тех строк типа char(N), длина которых меньше N (имеет место дополнение пробелами) или касается любых строк типа char(N) (даже если все строки в столбце будут иметь длину N) ?

https://www.postgresql.org/docs/current/datatype-binary.html
bytea = 1 or 4 bytes plus the actual binary string = variable-length binary string
4) В каких случаях 1 байт, в каких 4 байта ?
Судя по тому, что для типа bytea длину указать нельзя, имеется в виду фактическая длина байтовой строки...

Сообщение было отредактировано: 30 окт 20, 01:56
30 окт 20, 01:56    [22223322]     Ответить | Цитировать Сообщить модератору
 Re: character types: невнятная справка...  [new]
vyegorov
Member

Откуда: Рига
Сообщений: 1212
Cyrax_02,

1) заголовок строки добавляется (не включительно): в случае 10-байтовой строки будет 11 байт
2) речь о фактическом размере строки, а не об ограничении (CONSTRAINT) максимальной длины значения в колонке
3) возможно речь о том, что CHAR(N) добивается пробелами до заданной длины. у меня сомнения насчёт корректности этого утверждения, надо лезть в код. все 3 типа обслуживаются одинаковыми ф-циями, поэтому и сомнения
4) аналогично, заголовок зависит от длины фактического значения в байтах
30 окт 20, 02:35    [22223325]     Ответить | Цитировать Сообщить модератору
 Re: character types: невнятная справка...  [new]
Melkij
Member

Откуда: Санкт-Петербург
Сообщений: 1181
Cyrax_02
1) 126 байт включительно или невключительно ?

https://github.com/postgres/postgres/blob/REL_11_STABLE/src/include/postgres.h#L270
Включительно, но кроме строк нулевой длины. Для них однобайтовый заголовок неприменим.

Cyrax_02
2) требуется 1 байт дополнительной памяти для любых строк с типом varchar(N) / char(N), где N до 126
или для строк типа char(N) / varchar(N) / text с фактической длиной до 126 байт ?

Неверно оба.
Достаточно короткого заголовка для хранения varchar / text с фактической длиной по 126 байт или для char(N) где N <= 126

Cyrax_02
3) "because of its additional storage costs" - это касается только тех строк типа char(N), длина которых меньше N (имеет место дополнение пробелами) или касается любых строк типа char(N) (даже если все строки в столбце будут иметь длину N) ?

Здесь речь о необходимости дополнения пробелами до N и их хранении.

Cyrax_02
4) В каких случаях 1 байт, в каких 4 байта ?

Те самые 126 байт фактической длины строки.
30 окт 20, 11:02    [22223436]     Ответить | Цитировать Сообщить модератору
 Re: character types: невнятная справка...  [new]
Cyrax_02
Member

Откуда:
Сообщений: 1396
Melkij
Достаточно короткого заголовка для хранения varchar / text с фактической длиной по 126 байт или для char(N) где N <= 126
Так будет правильнее:
Достаточно короткого заголовка для хранения varchar / varchar(N) / text с фактической длиной <= 126 байт или для char(N) где N <= 126

vyegorov
3) возможно речь о том, что CHAR(N) добивается пробелами до заданной длины.
Melkij
Здесь речь о необходимости дополнения пробелами до N и их хранении.
Т.е. в случае, когда в поле сохраняются только строки длиной N, то в этом случае:
1) тип char(N) работать медленнее varchar(N) не будет (по основаниям, указанным в справке) ?
2) тип char(N) будет работать чуть быстрее, чем varchar(N), за счёт отсутствия проверки длины строки ?
3) тип char(N) будет работать не быстрее и не медленнее, чем varchar ?

Сообщение было отредактировано: 30 окт 20, 14:55
30 окт 20, 14:56    [22223578]     Ответить | Цитировать Сообщить модератору
 Re: character types: невнятная справка...  [new]
Melkij
Member

Откуда: Санкт-Петербург
Сообщений: 1181
Cyrax_02
1) тип char(N) работать медленнее varchar(N) не будет (по основаниям, указанным в справке) ?

Нет.

Cyrax_02
2) тип char(N) будет работать чуть быстрее, чем varchar(N), за счёт отсутствия проверки длины строки ?

Нет.

input функция - куда деть проверку длины? И добивание пробелами? Здесь они.
output - без разницы. Функции разные, код одинаковый
Операции над char(N), например, сравнение - обязаны выполняться без учёта концевых пробелов, а оттого добавляем обработку rtrim (bcTruelen там же) там где её нет для других типов данных.
30 окт 20, 15:22    [22223600]     Ответить | Цитировать Сообщить модератору
 Re: character types: невнятная справка...  [new]
Cyrax_02
Member

Откуда:
Сообщений: 1396
Melkij
сравнение - обязаны выполняться без учёта концевых пробелов, а оттого добавляем обработку rtrim
Ну да. Получается, char действительно, почти никогда и не нужен (как и написано в справке).
31 окт 20, 11:12    [22223890]     Ответить | Цитировать Сообщить модератору
 Re: character types: невнятная справка...  [new]
Cyrax_02
Member

Откуда:
Сообщений: 1396
Melkij
Те самые 126 байт фактической длины строки.
Что-то не сходится. pg_column_size показывает "всегда 4 байта + длина строки"
SELECT pg_column_size(''::varchar);   -- 4 (должно быть 1)
SELECT pg_column_size('5'::varchar);  -- 5 (должно быть 2)
SELECT pg_column_size(''::text);      -- 4 (должно быть 1)
SELECT pg_column_size('5'::text);     -- 5 (должно быть 2)
SELECT pg_column_size(''::bytea);     -- 4 (должно быть 1)
SELECT pg_column_size('\x00'::bytea); -- 5 (должно быть 2)
Т.е. на длину короткой строки выделяется 4 байта, а не 1.
19 ноя 20, 20:18    [22235680]     Ответить | Цитировать Сообщить модератору
 Re: character types: невнятная справка...  [new]
Maxim Boguk
Member

Откуда: Melbourne, Австралия
Сообщений: 4396
Cyrax_02,

все сходится вы неверно тестируете


create table test (val text);
CREATE TABLE
insert into test values (''),('5'),(repeat('a',255));
INSERT 0 3


select val, pg_column_size(val) from test;
-[ RECORD 1 ]--+----
val |
pg_column_size | 1

-[ RECORD 2 ]--+----
val | 5
pg_column_size | 2

-[ RECORD 3 ]--+-----
val | aaaa...aaaaaaaaaaaaaaaaaaa
pg_column_size | 259

varlenght prefix только для on-disk storage используется но не для in-memory representation
и этого в том числе касается текст из документации к функции " If applied directly to a table column value, this reflects any compression that was done."


--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
19 ноя 20, 20:46    [22235697]     Ответить | Цитировать Сообщить модератору
Все форумы / PostgreSQL Ответить