Хранение сериализованных объектов в MySQL и производительность

#php #mysql #serialization #innodb

#php #mysql #сериализация #innodb

Вопрос:

Мы хотим сохранить сериализованный объект в таблице вместе с уникальным внутренним идентификатором. Мы хотели бы только читать / записывать / (редко) обновлять строки. Мы никогда не будем взаимодействовать с сериализованным полем только по идентификатору. Мы используем InnoDB,

Во-первых;

Было бы правильно сохранить сериализацию в виде поля текстового типа?

Во-вторых;

Если мы напрямую не взаимодействуем с сериализованным полем, отличным от r / w, повлияет ли это вообще на производительность нашей базы данных?

Наконец;

Было бы лучше вместо этого сохранить сериализованный объект в нашей файловой системе?

Чтобы дать небольшое представление о том, почему мы храним их в первую очередь, мы получаем объект от поставщика, пользователю необходимо выбрать несколько вариантов, и нам нужно отправить ТОЧНЫЙ объект обратно с измененными (выбранными) компонентами.

Комментарии:

1. «Мы никогда не будем взаимодействовать с сериализованным полем только по идентификатору» — Что?

2. Извините, это трудно объяснить, я имею в виду, что мы никогда не хотели бы заказывать или искать поле. Я пытался избежать других случаев почти того же вопроса, когда люди хотели выполнять действия в указанном поле.

Ответ №1:

  1. Да, сохранение его в виде текстового поля (тип TEXT ) является правильным, но вы также можете сохранить его в двоичном формате (тип BLOB ), если вас беспокоит кодировка символов.

  2. Нет, если вы просматриваете только идентификатор, который является первичным ключом, то это не должно оказывать слишком большого влияния на производительность.

  3. Если вы используете MySQL для хранения идентификаторов, вы могли бы также сохранить сериализованный объект в таблице, если только у вас нет огромных объемов сериализованных данных, которые могут занимать много места на диске, но тогда при хранении их в файловой системе возникнет та же проблема.

Комментарии:

1. В этом поле TEXT также хранится информация о кодировке символов, которая нежелательна для таких действий, как сохранение сериализованного объекта. Это должно быть поле, в котором не хранится информация о кодировке, такая как BLOB или VARBINARY .

Ответ №2:

Во-первых;

Было бы правильно сохранить сериализацию в виде поля текстового типа?

Да, я предлагаю вам использовать для этого двоичную кодировку. Тогда лучше подойдет Blob, который является text IIRC. Просто предотвратите любое кодирование, просто сохраните его в двоичном виде.

Во-вторых;

Если мы напрямую не взаимодействуем с сериализованным полем, отличным от r / w, повлияет ли это вообще на производительность нашей базы данных?

Не более, как если бы это были какие-либо другие данные.

Наконец;

Было бы лучше вместо этого сохранить сериализованный объект в нашей файловой системе?

Поскольку это в основном меньшие фрагменты данных, я бы предпочел базу данных, поскольку она может лучше обрабатывать меньшие фрагменты данных, чем файловая система, которая имеет один файл на сериализованный фрагмент.

Ответ №3:

Это звучит как простая настройка ключ-> значение — одна таблица, два столбца, первичный ключ в первом и никаких дополнительных индексов. Если ваши объекты большие, MySQL для этого не подходит. Если они маленькие, у вас, вероятно, все в порядке. Я бы подумал, что все, что превышает 12 кб, слишком велико. Страницы InnoDB имеют размер 16 КБ, и если каждая запись с ее накладными расходами занимает более одной страницы, вы начинаете создавать беспорядок.

Файловые системы хорошо справляются с этим, если вы разбиваете объекты, используя соответствующее разделение папок. Обычно у них возникают проблемы, если у вас миллион файлов в одном каталоге. Где находится этот переломный момент, зависит от файловой системы, поэтому вам придется провести некоторое исследование. Это означает некоторый пользовательский код.

MongoDB действительно подходит для парадигмы ключ-> значение и лучше справляется с хранением объектов, чем MySQL.

В конце концов, если мы говорим о менее чем 1 000 000 записей и всего около 10 ГБ, просто выбросьте это в MySQL и двигайтесь дальше. Я думаю, что в тот момент, когда это имеет значение, вы все равно захотите сравнить.