У меня есть таблица:
CREATE TABLE `sessions` (
id BINARY(16) NOT NULL,
PRIMARY KEY(id)
) ENGINE=InnoDB;
Я создал значение для вставки в поле id
:
$sql = 'INSERT INTO sessions (id) VALUES(?)';
my $generator = Data::UUID->new;
my $session_id = $generator->create();
$result = $dbh->do($sql, undef, $session_id);
Согласно документации к модулю Data::UUID
:
# creates binary (16 byte long binary value) UUID.
$ug->create();
https://metacpan.org/pod/Data::UUID
Но когда я пытаюсь ВСТАВИТЬ данные, я получаю сообщение об ошибке от MariaDB:
Данные слишком длинные для столбца "id"
Почему оно слишком длинное, если длина поля составляет 16 байт и, согласно документации, размер $session_id также составляет 16 байт?
Я подозреваю, что проблема связана с драйвером: я подключаюсь с помощью "dbi:MariaDB:$dbinst:$dbhost"
, в то время как другой пользователь, который пробовал драйвер mysql
, не столкнулся с какими-либо ошибками.
🤔 А знаете ли вы, что...
SQL может выполнять соединение данных из нескольких таблиц с помощью операторов UNION и UNION ALL.
Лучше использовать тип UUID
в MariaDB и Data::UUID::create_str
. Это будет выглядеть примерно так:
CREATE TABLE `sessions` (
id UUID NOT NULL,
PRIMARY KEY(id)
) ENGINE=InnoDB;
$sql = 'INSERT INTO sessions (id) VALUES(?)';
my $generator = Data::UUID->new;
my $session_id = $generator->create_str();
$result = $dbh->do($sql, undef, $session_id);
Самое простое решение — просто использовать varchar(16)
, желательно с движком MyRocks
, если он доступен (MyRocks
значительно улучшит производительность и сжатие varchar-ключей):
CREATE TABLE `sessions` (
id VARCHAR(16) NOT NULL,
PRIMARY KEY(id)
) ENGINE=MyRocks;
$sql = 'INSERT INTO sessions (id) VALUES(?)';
my $generator = Data::UUID->new;
my $session_id = $generator->create_bin();
$result = $dbh->do($sql, undef, $session_id);
По какой-то причине Data::UUID
возвращает значение с length(?)
, варьирующимся от 23
до 27
байт, но char_length(?)
из 16
. Вероятно, это ошибка либо Data::UUID
, либо DBD::MariaDB
/DBD::mysql
.