Я наткнулся на пару дней, которые я не могу решить. Я знаю базовый MySql, но я пытался работать с SELECT для восстановления данных в JSON.
У меня есть таблица в базе данных с именем home_slider.
Внутри у меня есть следующие столбцы:
id_shop, id_lang, id_image and json_groups_id.
Это все поля INT, кроме json_groups_id, куда я вставляю файлы через json_econde.
JSON в поле «json_groups_id» имеет следующую структуру:
{"2": "Guest", "3": "Customer", "4": "Custom"}
Все эти данные сохраняются в простом виде.
В конце концов я нахожу себе разные похожие на это:
+------------+----------------+-----------------+-------------------------------+
| shop_id | id_lang | id_image | json_groups_id |
+------------+----------------+-----------------+--------------------------------+
| 1 | 1 | 2 | {"2": "Guest", "3": "Customer"} |
| 1 | 1 | 3 | {"1": "Visit", "4": "Other"} |
| 1 | 1 | 4 | {"2": "Guest", "5": "Test"}
+-------------+----------------+-----------------+--------------------------------+
Проблема возникает сейчас, учитывая массив, подобный этому [2,5,4].
Я хотел бы получить все строки, которые в поле «json_groups_id» имеют этот ключ.
Я пробовал с JSON_EXTRACT, но не смог.
Какой выбор я могу использовать?
Спасибо
Марио
Покажите свой запрос и версию MySql
TBH Я не очень доволен подходом к фильтрации данных непосредственно по столбцу, который содержит «необработанные данные»/поле объекта, такое как JSON. В качестве наивной идеи, не было бы более разумно изобразить такого рода ассоциации в отдельной таблице, чтобы вы могли запросить их просто по идентификатору?
в локальной версии 5.6.35
Я еще не видел ни одного вопроса на Stack Overflow о хранении JSON в MySQL, где использование JSON было хорошей идеей. Данные лучше хранить в нормализованном виде.
В MySQL 5.6 вы не можете использовать функции JSON. Взгляните на мой ответ здесь: stackoverflow.com/questions/37816269/… -- эти функции могут оказаться полезными и для вас.






Вы должны нормализовать свою базу данных, имея по крайней мере 3-ю нормальную форму. Так атомарные данные лежали бы в отдельном поле.
Затем вы можете легко выбрать данные, используя условие WHERE,
но в качестве костыля вы можете использовать LIKE для текущей структуры.
SELECT * FROM `table` WHERE `json_groups_id` LIKE '{"YOURNUMBER1"%' OR `json_groups_id` LIKE '{"YOURNUMBER2"%' OR `json_groups_id` LIKE '{"YOURNUMBER3"%'
Также вы можете попробовать JSON_CONTAINS()https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html
Но это не лучшая практика, имхо
Я тоже думаю, что это был бы выход. Разделите данные в другой таблице, чтобы вы могли легко запрашивать их без необходимости применять довольно медленные фильтры к столбцу. Отношение 1:N. Кроме того, это облегчит расширение в будущем.
Основываясь на предоставленной вами информации, я предполагаю, что вам нужно отношение M:N, чтобы отобразить вашу связь между данными JSON и исходной таблицей, которую вы описали в своем сообщении.
Ваша исходная таблица (обновлена)
+------------+----------------+------------+
| shop_id | id_lang | id_image |
+------------+----------------+------------+
| 1 | 1 | 2 |
| 1 | 1 | 3 |
| 1 | 1 | 4 |
+------------+----------------+------------+
Новая таблица
+-------------+----------------+
| group_id | desc/name |
+-------------+----------------+
| 1 | Visit |
| 2 | Guest |
| 3 | Customer |
| 4 | Other |
| 5 | Test |
+-------------+----------------+
Отношения/присоединение к таблице:
+-------------+-------------------+
| FK group_id | FK Original Table |
+-------------+-------------------+
| 1 | A |
| 1 | B |
| 2 | C |
| 4 | D |
| 5 | E |
+-------------+-------------------+
Очевидно, что в этом случае вам нужно либо сохранить JSON как дубликат, либо, что было бы еще лучше, и это также то, что я бы рекомендовал => восстановить его из данных, которые вы извлекаете из БД.
Приведенный выше пример таблицы является лишь намеком на то, как это можно реализовать на уровне БД. Если вам не нужна реконструкция данных, я бы вообще не стал беспокоиться об исходном JSON. Я не знаю, каков первичный ключ вашей исходной таблицы, поэтому я добавил общий ключ для таблицы соединений.
Обновлено: удалено 1:N, потому что требуется M:N.
хорошо, я, кажется, понял, что подход неправильный. Я пытаюсь создать две таблицы и связать их друг с другом. По сути, я хочу получить все id_image, принадлежащие одной или нескольким группам id_group, которые у меня есть в массиве. Теперь я пытаюсь связать таблицы, посмотрим, что произойдет
@Mariogasparella Если один и тот же идентификатор группы относится к разным строкам, вам нужно M: N и второй подход. Однако теперь я обновлю свой ответ, так как вам нужно M: N, насколько я понимаю. Потому что у вас один и тот же идентификатор группы в нескольких строках.
@Mariogasparella понять это без JSON в столбце гораздо проще и сложнее. Я знаю, что это может быть больше работы в первую очередь, но это путь. Кроме того, гораздо проще расширить, если вам нужно добавить больше информации в вашу группу.
спасибо, ребята, я должен был принять во внимание также директивы и бизнес-решения ... в то время, когда я использовал JSON_EXTRACT, но я переписываю код для создания реляционной таблицы. Большое спасибо за совет
Вы определенно можете это сделать, используя функцию JSON_EXTRACT() в mysql. Возможно, вы делаете ту или иную ошибку. Позвольте мне объяснить это на примере:
давайте возьмем таблицу, содержащую JSON (таблица client_services здесь):
+-----+-----------+--------------------------------------+
| id | client_id | service_values |
+-----+-----------+------------+-------------------------+
| 100 | 1000 | { "quota": 1,"data_transfer":160000} |
| 101 | 1000 | { "quota": 2,"data_transfer":800000} |
| 102 | 1000 | { "quota": 3,"data_transfer":70000} |
| 103 | 1001 | { "quota": 1,"data_transfer":97000} |
| 104 | 1001 | { "quota": 2,"data_transfer":1760} |
| 105 | 1002 | { "quota": 2,"data_transfer":1060} |
+-----+-----------+--------------------------------------+
Чтобы выбрать каждое поле JSON, выполните этот запрос:
SELECT
id, client_id,
json_extract(service_values, '$.quota') AS quota,
json_extract(service_values, '$.data_transfer') AS data_transfer
FROM client_services;
Таким образом, вывод будет:
+-----+-----------+----------------------+
| id | client_id | quota | data_transfer|
+-----+-----------+----------------------+
| 100 | 1000 | 1 | 160000 |
| 101 | 1000 | 2 | 800000 |
| 102 | 1000 | 3 | 70000 |
| 103 | 1001 | 1 | 97000 |
| 104 | 1001 | 2 | 1760 |
| 105 | 1002 | 2 | 1060 |
+-----+-----------+----------------------+
Я знаю, что вы пробовали это с помощью json_extract() , но это может быть так, что вы допустили небольшую ошибку. Внимательно изучите этот пример, я уверен, что он сработает.
Просто быстрая проверка... Какую версию MySQL вы используете?