Ошибка “Invalid utf8 character string” при записи бинарных данных в таблицу в MySQL

100
25 марта 2021, 19:40

При попытке записи в таблицу MySQL файла .png (пробовал для поля ставить blob и binary) - выдает ошибку:

Invalid utf8 character string '\x89PNG

Что я делаю не так?

Хранение в виде двоичных данных принципиально, т.к. далее будет интеграция с 1С на другом сервере: восстановление файла из двоичных данных.

Answer 1

Если забыть о том, что это вообще не самая лучшая идея - хранить файлы в реляционной БД (об этом ниже), то ваша проблема в том, что вы используете не тот тип колонки. Скорее всего у вас колонка типа TEXT:

MariaDB [test]> CREATE TABLE `example2` (`image` text);
Query OK, 0 rows affected (0.023 sec)
MariaDB [test]> INSERT INTO `example2` VALUES (LOAD_FILE('/tmp/example.png'));
Query OK, 1 row affected, 1 warning (0.002 sec)
MariaDB [test]> SHOW WARNINGS;
+---------+------+--------------------------------------------------------------------------------------------------+
| Level   | Code | Message                                                                                          |
+---------+------+--------------------------------------------------------------------------------------------------+
| Warning | 1366 | Incorrect string value: '\x89PNG\x0D\x0A...' for column `test`.`example2`.`image` at row 1 |
+---------+------+--------------------------------------------------------------------------------------------------+
1 row in set (0.000 sec)

Как видите, возникает ошибка. У меня другая версия БД, потому текст немного отличается - суть остаётся та же. Если попытаться выбрать данные из колонки, то вы получите побитую, нечитаемую, картинку.

Если же сделать колонку более подходящего для таких данных типа, то никаких проблем нет:

MariaDB [test]> CREATE TABLE `example` (`image` blob);
Query OK, 0 rows affected (0.021 sec)
MariaDB [test]> INSERT INTO `example` VALUES (LOAD_FILE('/tmp/example.png'));
Query OK, 1 row affected (0.002 sec)
MariaDB [test]> SHOW WARNINGS;
Empty set (0.000 sec)

Также стоит отметить что колонки типа TEXT и BLOB имеют максимальную длину порядка 64 килобайт, так что стоит обратить внимание на другие колонки с большей вместимость.

Почему хранить файлы в такой БД плохо? Потому что современные реляционные БД стараются отразить всю базу данных в оперативной памяти, и каждый добавленный файл будет почем зря использовать ценный и ограниченный ресурс сервера - оперативную память, которой часто всего несколько гигабайт, в отличии от терабайтов на жестком диске. Это только одна причина, есть и другие. Например, тот факт что реляционные БД не были задуманы для хранения файлов, и не работают с такими данными сколько-нибудь близко по эффективности файловых систем. И так далее, и тому подобное.

Answer 2

Видимо, вы пытаетесь подсунуть в место, где должен быть блоб, строку. Преобразуйте ее в блоб

https://www.php.net/manual/ru/function.fbsql-create-blob.php

READ ALSO
PhpSpreadsheet записать не считывая в память?

PhpSpreadsheet записать не считывая в память?

Использую либу "phpoffice/phpspreadsheet": "^15"

99
Вызов runnable в таймере

Вызов runnable в таймере

Есть ли проблема в этом коде:

105
Циклы ломают всё

Циклы ломают всё

Есть: массив StringBuilder but, StringBuilder str и массив int indexesДобавляю в массив строителей строки до тех пор, пока а меньше размера другого массива (в этом...

121
Подключение к камере Android

Подключение к камере Android

Пытаюсь выводить изображение с камеры на экран, делаю это так:

102