Какой тип столбца следует использовать для хранения сериализованных данных в базе данных MySQL? - PullRequest
48 голосов
/ 05 апреля 2011

Какой тип столбца следует использовать для хранения сериализованных данных в базе данных mysql?Я знаю, что вы можете использовать varbinary, blob, text.Что считается лучшим и почему?

Редактировать: я понимаю, что нехорошо хранить сериализованные данные.Мне нужно сделать это в этом одном случае, хотя.Пожалуйста, просто поверьте мне на это и сконцентрируйтесь на вопросе, если у вас есть ответ.Спасибо!

Ответы [ 8 ]

62 голосов
/ 28 сентября 2012

Чтобы ответить: кажется, что текст во многих СУБД устарел, поэтому лучше использовать большой двоичный объект или varchar с высоким пределом (а с blob вы не получите никаких проблем с кодировкой, что является большой проблемой с varchar) и текст).

Также, как указано в этой теме на форумах MySQL , жесткие диски дешевле, чем программное обеспечение, поэтому вам лучше сначала спроектировать свое программное обеспечение и заставить его работать, и только тогда, если пространство станет проблемой Вы можете оптимизировать этот аспект. Поэтому не пытайтесь слишком рано оптимизировать размер столбца, сначала лучше установить его больше (плюс это позволит избежать проблем с безопасностью).

О различных комментариях: Слишком много фанатизма SQL здесь. Несмотря на то, что я очень люблю SQL и реляционные модели, у них также есть свои подводные камни.

Хранение сериализованных данных в базе данных как есть (например, хранение данных в формате JSON или XML) имеет несколько преимуществ:

  • У вас может быть более гибкий формат для ваших данных: добавление и удаление полей на лету, изменение спецификации полей на лету и т. Д. *
  • Меньшее несоответствие импеданса объектной модели: вы сохраняете и извлекаете данные в том виде, как они есть в вашей программе, по сравнению с извлечением данных и последующей обработкой и преобразованием их между структурами ваших программных объектов и структурами вашей реляционной базы данных. .

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

Что касается конкретного примера использования, я склонен добавлять поле JSON в свою базу данных для хранения дополнительных параметров записи, в которой столбцы (свойства) данных JSON никогда не будут выбираться по отдельности, а только когда правильная запись уже выбрана. В этом случае я все еще могу различать свои записи с помощью реляционных столбцов, и когда выбрана правильная запись, я могу просто использовать дополнительные параметры для любой цели.

Так что мой совет, чтобы сохранить лучшее из обоих (скорость, сериализуемость и структурная гибкость), просто используйте несколько стандартных реляционных столбцов, которые будут служить уникальными ключами для разграничения ваших строк, а затем используйте столбец blob / varchar, где ваш сериализованные данные будут вставлены. Обычно для уникального ключа требуются только два / три столбца, поэтому это не потребует больших затрат.

Кроме того, вас может заинтересовать PostgreSQL, который теперь имеет тип данных JSON, и проект PostSQL для непосредственной обработки полей JSON как реляционных столбцов.

11 голосов
/ 05 апреля 2011

Сколько вы планируете хранить? Ознакомьтесь со спецификациями для строковых типов в документации MySQL и их размеров . Ключевым моментом здесь является то, что вам не нужно индексировать этот столбец, но вы также никогда не хотите, чтобы он переполнялся и обрезался, поскольку тогда ваш JSON не читается.

  • TINYTEXT L <2 ^ 8 </li>
  • ТЕКСТ L <2 ^ 16 </li>
  • СРЕДНИЙ ТЕКСТ L <2 ^ 24 </li>
  • LONGTEXT L <2 ^ 32 </li>

Где L - длина символа

Достаточно просто text должно быть достаточно, но увеличьте его, если вы храните больше. Хотя, в этом случае, вы можете не захотеть хранить его в БД.

10 голосов
/ 18 августа 2011

Ограничения длины, о которых упоминает @Twisted Pear, являются вескими причинами.

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

Обратите внимание, что вы все еще можете хранить текстовые данные в BLOB, вы просто не можете выполнять над ним какие-либо операции SQL, учитывающие кодировку; это просто байты в SQL. Но это, вероятно, не проблема в вашем случае, так как это сериализованные данные со структурой, неизвестной SQL в любом случае. Все, что вам нужно сделать, это хранить байты и извлекать байты. Интерпретация байтов зависит от вашего приложения.

У меня также были проблемы с использованием LONGBLOB или LONGTEXT с использованием определенных клиентских библиотек (например, PHP), потому что клиент пытается выделить буфер настолько большим, насколько это возможно, не зная, насколько большим будет содержимое. любой заданный ряд, пока он не извлечен. Это привело к тому, что PHP загорелся, пытаясь выделить 4 ГБ буфера. Я не знаю, каким клиентом вы пользуетесь, или страдает ли он тем же поведением.

Обходной путь: используйте MEDIUMBLOB или просто BLOB, если этих типов достаточно для хранения ваших сериализованных данных.


Что касается людей, которые говорят вам не делать этого, я не буду вам этого говорить (несмотря на то, что я сторонник SQL). Это правда, что вы не можете использовать выражения SQL для выполнения операций над отдельными элементами в сериализованных данных, но это не ваша цель. Что вы получаете, помещая эти данные в базу данных, так это:

  • Свяжите сериализованные данные с другими более реляционными данными.
  • Возможность хранить и извлекать сериализованные данные в соответствии с областью транзакции, COMMIT, ROLLBACK.
  • Храните все ваши реляционные и нереляционные данные в одном месте, чтобы упростить их репликацию на ведомые устройства, резервное копирование и восстановление и т. Д.
7 голосов
/ 18 августа 2011

LONGTEXT

Wordpress сохраняет сериализованные данные в своей таблице postmeta как LONGTEXT.Я считаю, что база данных Wordpress является хорошим местом для исследования типов данных для столбцов.

2 голосов
/ 06 декабря 2017

Я могу опоздать на вечеринку, но в документации php.net о сериализованном объекте говорится следующее:

Обратите внимание, что это двоичная строка, которая может содержать нулевые байты, и должен храниться и обрабатываться как таковой. Например, serialize () выходные данные, как правило, должны храниться в поле BLOB в базе данных, а не поле CHAR или TEXT.

Источник: http://php.net/manual/en/function.serialize.php

Надеюсь, это поможет!

2 голосов
/ 01 декабря 2015

Начиная с MySQL 5.7.8, MySQL поддерживает собственный тип данных JSON: Руководство по MySQL

0 голосов
/ 21 августа 2011

Я нашел:

varchar(5000)

- это лучший баланс размера / скорости для нас.Кроме того, он работает с сериализацией данных rails 3 (varbinary) периодически выбрасывал ошибки сериализации.

0 голосов
/ 05 апреля 2011

Если сериализованные данные не имеют другого использования, кроме как для сохранения и восстановления из базы данных, вы, вероятно, не захотите делать это таким образом.

Как правило, сериализованные данные имеют несколько полей, которые следует хранитьв базе данных в виде отдельных столбцов.Обычно каждый элемент сериализованных данных представляет собой отдельный столбец.Некоторые из этих столбцов, естественно, будут ключевыми полями.Помимо данных, возможно, могут быть добавлены дополнительные столбцы, чтобы указать дату + время, когда произошла вставка, ответственного пользователя и т. Д. И т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...