Хранение данных в MySQL как JSON

Я думал, что это нужно сделать n00b. И поэтому я никогда этого не делал. Затем я увидел, что FriendFeed сделал это и фактически улучшил свою шкалу БД и уменьшил задержку. Мне интересно, если я это сделаю. И если да, то какой правильный способ это сделать?

В принципе, какое хорошее место, чтобы узнать, как хранить все в MySQL как Bouch CCDDB? Хранение всего, как JSON, похоже, было бы проще и быстрее (не строить, меньше латентности).

Кроме того, легко ли редактировать, удалять и т.д. вещи, хранящиеся как JSON в БД?

Ответ 1

CouchDB и MySQL - это два совершенно разных зверя. JSON - это родной способ хранения файлов в CouchDB. В MySQL лучшее, что вы можете сделать, это хранить данные JSON в виде текста в одном поле. Это полностью уничтожило бы цель хранения его в СУБД и значительно усложняло бы каждую транзакцию базы данных.

Не нужно.

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

Ответ 2

Кажется, что все комментируют это с неправильного угла, хорошо хранить JSON-код через PHP в реляционной БД, и на самом деле будет быстрее загружать и отображать сложные данные, подобные этому, однако у вас будет дизайн такие как поиск, индексирование и т.д.

Лучший способ сделать это - использовать гибридные данные, например, если вам нужно искать на основе datetime MySQL (настройка производительности) будет намного быстрее, чем PHP, и для чего-то вроде поиска расстояния от мест, где MySQL также должен быть намного быстрее (обратите внимание на поиск, не доступ). Данные, которые вам не нужно искать, могут затем храниться в JSON, BLOB или в любом другом формате, который вы действительно считаете необходимым.

Данные, которые вам нужно получить, очень легко сохраняются как JSON, например, базовая система счетов для каждого случая. Они вообще ничего не выигрывают от СУБД и могут быть сохранены в JSON только json_encoding ($ _ POST ['entires']), если у вас есть правильная структура HTML-формы.

Я рад, что вы счастливы в использовании MongoDB, и я надеюсь, что он продолжает служить вам хорошо, но не думайте, что MySQL всегда будет отключен от вашего радара, так как ваше приложение будет увеличиваться по сложности, вы, возможно, RDBMS для некоторых функций и функций (даже если это просто для удаления архивных данных или бизнес-отчетов)

Ответ 3

MySQL 5.7 Теперь поддерживает родной тип данных JSON, аналогичный MongoDB и другим хранилищам данных, хранящихся в схемах:

Поддержка JSON

Начиная с MySQL 5.7.8, MySQL поддерживает родной тип JSON. Значения JSON не сохраняются в виде строк, а используют внутренний двоичный формат, который позволяет быстро читать доступ к элементам документа. Документы JSON, хранящиеся в столбцах JSON, автоматически проверяются всякий раз, когда они вставлены или обновлены, а недопустимый документ создает ошибку. Документы JSON нормализуются при создании и могут сравниваться с использованием большинства операторов сравнения, таких как =, <, < =, > , > =, < > ,!= И <= > ; для получения информации о поддерживаемых операторах, а также о приоритетах и ​​других правилах, которые MySQL следует при сравнении значений JSON, см. в разделе Сравнение и порядок значений JSON.

MySQL 5.7.8 также вводит ряд функций для работы со значениями JSON. Эти функции включают перечисленные здесь функции:

  • Функции, которые создают значения JSON: JSON_ARRAY(), JSON_MERGE() и JSON_OBJECT(). См. Раздел 12.16.2, "Функции, которые создают значения JSON".
  • Функции, которые ищут значения JSON: JSON_CONTAINS(), JSON_CONTAINS_PATH(), JSON_EXTRACT(), JSON_KEYS() и JSON_SEARCH(). См. Раздел 12.16.3, "Функции, которые ищут значения JSON".
  • Функции, которые изменяют значения JSON: JSON_APPEND(), JSON_ARRAY_APPEND(), JSON_ARRAY_INSERT(), JSON_INSERT(), JSON_QUOTE(), JSON_REMOVE(), JSON_REPLACE(), JSON_SET() и JSON_UNQUOTE(). См. Раздел 12.16.4 "Функции, изменяющие значения JSON".
  • Функции, которые предоставляют информацию о значениях JSON: JSON_DEPTH(), JSON_LENGTH(), JSON_TYPE() и JSON_VALID(). См. Раздел 12.16.5 "Функции, возвращающие атрибуты значения JSON".

В MySQL 5.7.9 и более поздних версиях вы можете использовать column- > path как сокращенное обозначение JSON_EXTRACT (столбец, путь). Это работает как псевдоним для столбца, где идентификатор столбца может встречаться в операторе SQL, включая предложения WHERE, ORDER BY и GROUP BY. Это включает в себя команды SELECT, UPDATE, DELETE, CREATE TABLE и другие SQL-запросы. Левая сторона должна быть идентификатором столбца JSON (а не псевдонимом). Правая сторона - это цитированное выражение пути JSON, которое оценивается по отношению к документу JSON, возвращаемому как значение столбца.

См. Раздел 12.16.3, "Функции, которые ищут значения JSON", для получения дополнительной информации о → и JSON_EXTRACT(). Сведения о поддержке путей JSON в MySQL 5.7 см. В разделе "Поиск и изменение значений JSON". См. Также Вторичные индексы и виртуальные созданные столбцы.

Дополнительная информация:

https://dev.mysql.com/doc/refman/5.7/en/json.html

Ответ 4

json-символы ничего особенного, когда дело доходит до хранения, такие символы, как

{, }, [, ], ', a-z, 0-9.... действительно ничего особенного и могут храниться как текст.

Первая проблема, с которой вам придется столкнуться, - это

{   profile_id: 22,   имя пользователя: "Роберт",   пароль: 'skhgeeht893htgn34ythg9er' }

который хранится в базе данных, не так просто обновить, если у вас не было собственного устройства, и разработал jsondecode для mysql

UPDATE users SET JSON(user_data,'username') = 'New User';

Так как вы не можете сделать это, вам придется сначала SELECT json, декодировать его, изменить его, обновить, поэтому теоретически вы можете потратить больше времени на создание подходящей структуры базы данных!

Я использую json для хранения данных, но только Meta Data, данные, которые не обновляются часто, не связаны с конкретным пользователем. Например, если пользователь добавляет сообщение, и в этом сообщении он добавляет изображения, которые плохо анализируют изображения и создавать большие пальцы, а затем использовать URL-адреса большого пальца в формате json.

Ответ 5

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

Он не учитывает массивы или другие объекты, просто базовые типы данных. Вы должны изменить 4 экземпляра столбца на имя столбца, хранящее JSON, и изменить 4 экземпляра myfield в поле JSON, к которому вы хотите получить доступ.

SELECT
    SUBSTRING(
        REPLACE(REPLACE(REPLACE(column, '{', ''), '}', ','), '"', ''),
        LOCATE(
            CONCAT('myfield', ':'),
            REPLACE(REPLACE(REPLACE(column, '{', ''), '}', ','), '"', '')
        ) + CHAR_LENGTH(CONCAT('myfield', ':')),
        LOCATE(
            ',',
            SUBSTRING(
                REPLACE(REPLACE(REPLACE(column, '{', ''), '}', ','), '"', ''),
                LOCATE(
                    CONCAT('myfield', ':'),
                    REPLACE(REPLACE(REPLACE(column, '{', ''), '}', ','), '"', '')
                ) + CHAR_LENGTH(CONCAT('myfield', ':'))
            )
        ) - 1
    )
    AS myfield
FROM mytable WHERE id = '3435'

Ответ 6

Это действительно зависит от вашего варианта использования. Если вы храните информацию, которая абсолютно не имеет значения в отчетности, и не будет запрашиваться через JOINs с другими таблицами, вам может понадобиться хранить ваши данные в одном текстовом поле, закодированном как JSON.

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

Ответ 7

Я бы сказал, что только две причины для этого:

  • производительность просто недостаточна с нормализованным подходом
  • вы не можете легко моделировать ваши текущие/гибкие/изменяющиеся данные.

Я немного написал о моем собственном подходе:

С какими проблемами масштабируемости вы столкнулись с использованием хранилища данных NoSQL?

(см. верхний ответ)

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

Есть ли причина, по которой вы не используете что-то вроде MongoDB? (может быть MySQL "требуется", просто любопытно)

Ответ 8

Это старый вопрос, но я все еще могу видеть это в верхней части результата поиска Google, поэтому, я думаю, было бы полезно добавить новый ответ через 4 года после запроса.

Прежде всего, есть лучшая поддержка при хранении JSON в РСУБД. Вы можете перейти на PostgreSQL (хотя MySQL поддерживает JSON с версии v.7.7.7). PostgreSQL использует очень похожие SQL-команды как MySQL, за исключением того, что они поддерживают больше функций. Одна из функций, которые они добавили, заключается в том, что они предоставляют тип данных JSON, и теперь вы можете запросить сохраненный JSON. (Некоторая ссылка на это). Если вы не составляете запрос непосредственно в своей программе, например, используя PDO в php или eloquent в Laravel, все, что вам нужно сделать, это просто установить PostgreSQL на свой сервер и изменить настройки подключения к базе данных. Вам даже не нужно менять код.

В большинстве случаев, как указывали другие ответы, хранение данных как JSON непосредственно в СУБД не является хорошей идеей. Однако есть какое-то исключение. Одна из ситуаций, о которых я могу думать, - это поле с переменным числом связанных записей.

Например, для хранения тега сообщения в блоге обычно вам нужно иметь таблицу для сообщения в блоге, таблицу тегов и соответствующую таблицу. Поэтому, когда пользователь хочет отредактировать сообщение, и вам нужно показать, какой тег связан с этим сообщением, вам нужно запросить 3 таблицы. Это может повредить производительность, если ваша таблица таблиц/тегов длинна.

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

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

Ответ 9

Вот функция, которая будет сохранять/обновлять ключи массива JSON в столбце и другую функцию, которая извлекает значения JSON. Эти функции создаются при условии, что имя столбца хранения массива JSON json. Он использует PDO.

Сохранить/Обновить функцию

function save($uid, $key, $val){
 global $dbh; // The PDO object
 $sql = $dbh->prepare("SELECT `json` FROM users WHERE `id`=?");
 $sql->execute(array($uid));
 $data      = $sql->fetch();
 $arr       = json_decode($data['json'],true);
 $arr[$key] = $val; // Update the value
 $sql=$dbh->prepare("UPDATE `users` SET `json`=? WHERE `id`=?");
 $sql->execute(array(
   json_encode($arr), 
   $uid
 ));
}

где $uid - это идентификатор пользователя, $key - ключ JSON для обновления, и это значение упоминается как $val.

Получить значение Функция

function get($uid, $key){
 global $dbh;
 $sql = $dbh->prepare("SELECT `json` FROM `users` WHERE `id`=?");
 $sql->execute(array($uid));
 $data = $sql->fetch();
 $arr  = json_decode($data['json'], true);
 return $arr[$key];
}

где $key - это ключ массива JSON, из которого нам нужно значение.

Ответ 10

Мне кажется, что все, кто отвечает на этот вопрос, относятся к одной важной проблеме, за исключением @deceze - использовать правильный инструмент для задания. Вы можете заставить реляционную базу данных хранить практически любой тип данных, и вы можете заставить Mongo обрабатывать реляционные данные, но по какой цене? Вы в конечном итоге вводите сложность на всех уровнях разработки и обслуживания, от проектирования схемы до кода приложения; не говоря уже о производительности.

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

  • Mongo (хранение документов)
  • Redis (хранилище данных с ключом)
  • MySQL/Maria/PostgreSQL/Oracle/etc (реляционные данные)
  • CouchDB (JSON)

Я уверен, что пропустил других, таких как RabbirMQ и Cassandra. Я хочу сказать, что используйте нужные инструменты для хранения данных.

Если вашему приложению требуется хранить и извлекать различные данные на самом деле, очень быстро, (а кто нет) не уклоняются от использования нескольких источников данных для приложения. Самые популярные веб-фреймворки обеспечивают поддержку нескольких источников данных (Rails, Django, Grails, Cake, Zend и т.д.). Эта стратегия ограничивает сложность одной конкретной области приложения, ORM или интерфейса источника данных приложения.

Ответ 11

Ранняя поддержка хранения JSON в MySQL была добавлена ​​в MySQL 5.7.7. Выпущена лаборатория JSON (linux binaries, источник)! Похоже, что релиз вырос из серии пользовательских функций, связанных с JSON, которые были опубликованы еще в 2013 году.

Эта зарождающаяся нативная поддержка JSON, похоже, движется в очень позитивном направлении, включая проверку JSON на INSERT, оптимизированный формат двоичного хранения, включая таблицу поиска в преамбуле, которая позволяет функции JSN_EXTRACT выполнять двоичный поиск, а не анализировать на каждом доступ. Существует также целый ряд новых функций для обработки и запросов к конкретным типам данных JSON:

CREATE TABLE users (id INT, preferences JSON);

INSERT INTO users VALUES (1, JSN_OBJECT('showSideBar', true, 'fontSize', 12));

SELECT JSN_EXTRACT(preferences, '$.showSideBar') from users;

+--------------------------------------------------+
| id   | JSN_EXTRACT(preferences, '$.showSideBar') |
+--------------------------------------------------+
| 1    | true                                      |
+--------------------------------------------------+

IMHO, вышеизложенное является большим вариантом использования для этой новой функциональности; многие базы данных SQL уже имеют пользовательскую таблицу и вместо того, чтобы делать бесконечные изменения схемы, чтобы соответствовать изменяющемуся набору пользовательских предпочтений, имея один столбец JSON, единственный прокси JOIN идеально подходит. Тем более, что маловероятно, что ему когда-либо понадобится запрашивать отдельные предметы.

Пока еще рано, команда сервера MySQL отлично справляется с изменениями on .

Ответ 12

JSON является допустимым типом данных в базе данных PostgreSQL. Однако база данных MySQL официально не поддерживала JSON. Но это выпечка: http://mysqlserverteam.com/json-labs-release-native-json-data-type-and-binary-format/

Я также согласен с тем, что существует много действительных случаев, когда некоторые данные лучше сериализуются в строку в базе данных. Основная причина может заключаться в том, что она не будет регулярно запрашиваться, и когда собственная схема может измениться - вы не хотите изменять схему базы данных, соответствующую этому. Вторая причина заключается в том, что сериализованная строка напрямую связана с внешними источниками, вы не можете анализировать их все и загружать в базу данных любой ценой, пока не будете использовать их. Поэтому я буду ждать, когда новая версия MySQL будет поддерживать JSON, так как теперь будет проще переключаться между разными базами данных.

Ответ 13

Я использую json для записи чего-либо для проекта, я использую три таблицы на самом деле! один для данных в json, один для индекса каждой метаданных json-структуры (каждая мета кодируется уникальным идентификатором), а другая для пользователя сеанса - все. Баланс не может быть определен количественно в этом раннем состоянии кода, но, к примеру, я был просмотром пользователя (внутреннее соединение с индексом), чтобы получить категорию (или что-нибудь, как пользователь,...), и это было очень медленно (очень очень медленно, используемое представление в mysql не является хорошим способом). Модуль поиска в этой структуре может делать все, что я хочу, но, я думаю, что mongodb будет более эффективным в этой концепции полной записи данных json. Для моего примера я понимаю, что я создаю древо категории, и хлеб, мой бог! так много запросов сделать! Apache сам ушел! и, на самом деле, для этого небольшого веб-сайта я использую знать php, который генерирует дерево и breadcrumb, извлечение данных выполняется с помощью модуля поиска (который использует только индекс), таблица данных используется только для обновления. Если я хочу, я могу уничтожить все индексы и регенерировать их с каждым данным и выполнить обратную работу, например, уничтожить все данные (json) и восстановить его только с помощью индексной таблицы. Мой проект молод, работает под php и mysql, но иногда я использую node js и mongodb для этого проекта.

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

Низкая

французский пользователь

Ответ 14

Я считаю, что хранение JSON в базе данных mysql фактически наносит ущерб использованию RDBMS, поскольку оно предназначено для использования. Я бы не использовал его в каких-либо данных, которые будут обрабатываться в какой-то момент или сообщаться, поскольку это не только добавляет сложности, но также может легко влиять на производительность в зависимости от того, как она используется.

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

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

Ответ 15

Вы можете использовать этот метод: https://gist.github.com/AminaG/33d90cb99c26298c48f670b8ffac39c3

После установки его на сервер (просто нужно иметь привилегии root не супер), вы можете сделать что-то вроде этого:

select extract_json_value('{"a":["a","2"]}','(/a)')

Он вернется a 2 . Вы можете вернуть что-нибудь в JSON, используя это Хорошая часть заключается в том, что это поддержка MySQL 5.1.5.2.5.6. И вам не нужно устанавливать на сервер никаких двоичных файлов.

На основе старого проекта common-schema, но он все еще работает сегодня https://code.google.com/archive/p/common-schema/