Впервые в своей «реальной» жизни я буду использовать двоичный тип данных. Нам нужно сохранить какой-то штрих-код.
Мой старший член команды сказал мне, что мне следует использовать varbinary
, потому что это рекомендация из документации (мы используем Vertica).
Я сказал «хорошо», но мое любопытство подсказывало мне: «Почему?»
Я думал, что после выбора типы varbinary
или binary
будут печататься на экране в виде нечитаемого текста. Но этого не происходит.
Итак, я протестировал Vertica и SQLite, и они дали мне правильный ответ.
Я создаю таблицу и вставляю данные.
create table TEST_VARBINARY_2
(
id int,
va_r binary(5)
);
insert into TEST_VARBINARY_2 (id, va_r)
values (1, '11111')
И это ответ.
Очевидно, база данных может хранить строку в файле varbinary
.
Итак, мой вопрос: почему мы используем char/varchar
вместо varbinary/binary
?
Типы Varbinary/binary
могут хранить данные более эффективно, чем varchar/char
— так зачем нам varchar/char
?
Не могли бы вы привести мне примеры или ссылку на документацию, когда обсуждается этот вопрос?
UDP Думаю, в разделе комментариев я нашел ответ.
Связанный: В чем преимущество использования varbinary перед varchar? , почему varbinary вместо varchar , В чем разница между «VARCHAR BINARY» и «VARBINARY» в MySQL? . Индексирование столбца varbinary, varchar и int — это быстро. VARBINARY существует не в каждой БД, поэтому я предлагаю вам пометить свой вопрос той БД, которую вы используете. Вы сказали, что тестировали SQLite, но это не значит, что вы его используете.
va_r varchar(30)
Я думал, ты тестируешь варбинарий? Но это варчар...
@JohnGordon о va_r varchar(30)
. Это моя ошибка. Я скопировал неправильный sql. Зафиксированный)
@TheNomad Я использовал sqllite просто для быстрого тестирования. Просто создайте простую таблицу и посмотрите, как она будет выглядеть в select.
@marc_s я использовал Vertica DB. Но я думаю, что ваш комментарий является ответом. Я не думал о строковых функциях и т.д.
По сути, потому что байты — это не то же самое, что символы.
BINARY
/VARBINARY
хранить строки байтов. Но эти байты могут соответствовать печатным символам ASCII.
https://docs.vertica.com/24.1.x/en/sql-reference/data-types/binary-data-types-binary-and-varbinary/ говорит:
Как и входной формат, выходной формат представляет собой гибрид восьмеричных кодов и печатных символов ASCII. Байт в диапазоне печатаемых символов ASCII (диапазон
[0x20, 0x7e]
) представлен соответствующим символом ASCII, за исключением обратной косой черты ('\'
), которая экранируется как'\\'
. Все остальные байтовые значения представлены соответствующими восьмеричными значениями. Например, байты{97,92,98,99}
, которые в ASCII обозначаются{a,\,b,c}
, переводятся в текст как'a\\bc'
.
Вот почему ваша строка '1111'
печатается нормально. Это печатные символы ASCII. На самом деле это значение байта 49, но при выводе на текстовый дисплей они являются печатными символами.
Эти типы двоичных строк хранят только байты. Если вы хотите хранить символы, использующие другую кодировку, кроме ASCII, или использовать параметры сортировки для сортировки и сравнения символов, вы должны использовать CHAR
/VARCHAR
и, возможно, локаль.
Вы сказали, что используете Vertica. https://docs.vertica.com/24.1.x/en/admin/about-locale/locale-and-utf-8-support/ говорит:
Серверы баз данных Vertica ожидают получения всех данных в формате UTF-8, а Vertica выводит все данные в формате UTF-8.
Следующие строковые функции обрабатывают аргументы
VARCHAR
как строки UTF-8 (еслиUSING OCTETS
не указан) независимо от настроек локали.
(за которым следует список строковых функций)
Поскольку символы UTF-8 имеют переменную длину, длина строки в символах может отличаться от длины в байтах. Строковая функция LENGTH()
сообщает CHARACTER_LENGTH()
, когда ей дан аргумент CHAR
/VARCHAR
, но сообщает OCTET_LENGTH()
, когда ей дан аргумент BINARY
/VARBINARY
.
Сортировка — еще одно важное свойство строк. При сортировке двоичных данных для порядка используются значения байтов. Аналогично, при сортировке символьных данных с помощью двоичной сортировки. Но если вам нужна точная сортировка для определенной локали, порядок байтов не обязательно будет правильным для данной локали.
Прочтите https://docs.vertica.com/24.1.x/en/admin/about-locale/, чтобы узнать больше о локали в Vertica.
Для какой СУБД это? Во многих СУБД двоичные типы данных не позволяют манипулировать хранящимися в них текстовыми данными — так что само по себе это может быть действительно веской причиной использовать
(var)char
вместо всегда двоичных.