Przechowywanie danych w MySQL jako JSON

121

Myślałem, że to rzecz n00b. Dlatego nigdy tego nie robiłem. Potem zobaczyłem, że FriendFeed to zrobił i faktycznie poprawił ich skalę DB i zmniejszył opóźnienie. Ciekaw jestem, czy powinienem to zrobić. A jeśli tak, to jak to zrobić?

Zasadniczo, jakie jest dobre miejsce, aby dowiedzieć się, jak przechowywać wszystko w MySQL jako rodzaj bazy danych CouchDB? Przechowywanie wszystkiego w formacie JSON wydaje się być łatwiejsze i szybsze (nie budować, mniej opóźnień).

Czy łatwo jest edytować, usuwać itp. Rzeczy przechowywane w bazie danych jako JSON?

Oscar Godson
źródło
Dla porównania, uważam, że jest to dyskusja FriendFeed na temat używania JSON w MySQL: backchannel.org/blog/friendfeed-schemaless-mysql
dimo414
10
MySQL 5.7 obsługuje teraz natywny magazyn danych JSON.
eecue

Odpowiedzi:

57

CouchDB i MySQL to dwie bardzo różne bestie. JSON to natywny sposób przechowywania rzeczy w CouchDB. W MySQL najlepsze, co możesz zrobić, to przechowywać dane JSON jako tekst w jednym polu. To całkowicie zniweczyłoby cel przechowywania go w RDBMS i znacznie skomplikowałoby każdą transakcję w bazie danych.

Nie.

Powiedziawszy to, FriendFeed zdawał się używać wyjątkowo niestandardowego schematu oprócz MySQL. To naprawdę zależy od tego, co dokładnie chcesz przechowywać, nie ma jednej jednoznacznej odpowiedzi, jak nadużywać systemu baz danych, więc ma to dla Ciebie sens. Biorąc pod uwagę, że artykuł jest bardzo stary, a ich głównym powodem przeciwko Mongo i Couch była niedojrzałość, ponownie oceniłbym te dwa artykuły, jeśli MySQL nie zrobi tego za Ciebie. Powinni byli już dużo urosnąć.

zamrozić
źródło
3
Tak, patrzę na Mongo, a php ma do niego rozszerzenie, a rzeczywista składnia transakcji DB wydaje się łatwiejsza niż MySQL, a ogólna praca z tym wydaje się łatwiejsza niż couchDB. Dzięki, myślę, że pójdę z MongoDB :)
Oscar Godson
68
Z pewnością istnieją ważne przypadki przechowywania obiektów blob JSON w RDBMS. Jeśli chcesz po prostu przechowywać i pobierać nieprzezroczyste bloki danych JSON bez konieczności wykonywania zapytań o te dane, co zdarza się dość często w niektórych scenariuszach, możesz to zrobić.
markus
9
@markus Robię to w jednej z moich witryn internetowych, a konkretnie w polach o skomplikowanym formularzu, których nigdy nie szuka się bezpośrednio w zapytaniach MySQL, ale używam ich podczas przeglądania formularzy (z widoku tabeli lub bezpośrednio przez łącze). Prawdopodobnie nie jest to idealne rozwiązanie, ale z pewnością znacznie przyspiesza wdrażanie i eliminuje potrzebę stosowania nadmiernej liczby tabel lub kolumn tabeli.
Nick Bedford
1
Jeśli chcesz mieć zarówno RDBMS, jak i przechowywanie typów dokumentów dla swojej aplikacji, jest to dobre podejście, aby nie musieć zarządzać wieloma bazami danych.
rjarmstrong
5
To dość krótka rada, być może od kogoś, kto spędza zbyt dużo czasu na wymianie stosów? Kiedy mam rekord ze 100 polami, które chcę przechowywać i muszę przeszukiwać tylko 3 lub 4 pola, tworzenie tabeli ze 100 polami jest bezsensowne. Możesz przechowywać rekord klienta z całą jego książką adresową przechowywaną w jednym polu w formacie JSON i po prostu dodać identyfikator klienta, nazwisko, firmę jako inne pola do wyszukiwania rekordów. To jest. ogromna oszczędność czasu.
Danial
102

Wydaje się, że wszyscy komentujący podchodzą do tego z niewłaściwego punktu widzenia, dobrze jest przechowywać kod JSON przez PHP w relacyjnej bazie danych i w rzeczywistości ładowanie i wyświetlanie złożonych danych będzie szybsze, jednak będziesz mieć względy projektowe, takie jak wyszukiwanie, indeksowanie itp.

Najlepszym sposobem na to jest użycie danych hybrydowych, na przykład jeśli potrzebujesz wyszukiwania w oparciu o datę i godzinę MySQL (dostrojona wydajność) będzie dużo szybsze niż PHP, a dla czegoś takiego jak wyszukiwanie odległości lokalizacji MySQL powinien również być dużo szybciej (zauważ, że wyszukiwanie nie ma dostępu). Dane, których nie musisz szukać, mogą być następnie przechowywane w formacie JSON, BLOB lub innym formacie, który naprawdę uznasz za potrzebny.

Dane, do których potrzebujesz dostępu, są bardzo łatwo przechowywane jako JSON, na przykład podstawowy system fakturowania dla poszczególnych przypadków. Nie korzystają zbytnio z RDBMS i mogą być przechowywane w JSON po prostu przez json_encoding ($ _ POST ['entires']), jeśli masz poprawną strukturę formularza HTML.

Cieszę się, że jesteś zadowolony z korzystania z MongoDB i mam nadzieję, że nadal będzie ci dobrze służyć, ale nie myśl, że MySQL zawsze będzie poza zasięgiem twojego radaru, ponieważ twoja aplikacja staje się coraz bardziej złożona, możesz potrzebować RDBMS dla niektóre funkcje i funkcje (nawet jeśli służą tylko do wycofywania zarchiwizowanych danych lub raportowania biznesowego)

Lewis Richard Phillip Cowles
źródło
8
-1 dla „dobrze jest przechowywać kod JSON przez PHP w relacyjnej bazie danych” - Przechowywanie JSON (który może reprezentować całą jednostkę jako dane nieatomowe) w pojedynczym polu narusza model relacyjny i uniemożliwia 1NF. Nie rób też rozległych twierdzeń o wydajności bez danych, które Cię potwierdzą.
Sage Gerard
80
Jak wspomniano, zależy to od tego, co przechowujesz, tj. Czy naprawdę musisz przechowywać każdy wpis osobno w przypadku faktury? NIE, twój komentarz wygląda tak, jakbyś wiedział tak dużo, ale 1NF nie jest dla każdego pola lub nie byłoby BLOB i typów tekstowych ... to czysty nonsens dla systemu produkcyjnego, musisz tylko zoptymalizować to, czego potrzebujesz do wyszukiwania tj. daty, klucze i ustawianie indeksów na niektórych danych. Nie powiedziałem, że przechowuj wszystko jako JSON, powiedziałem, że przechowuj niektóre dane jako JSON, jeśli pomoże to rozwiązać problem.
Lewis Richard Phillip Cowles
2
To, co mówisz, jest możliwe i wygodne, ale odejście od dobrze ukształtowanych relacji oznacza więcej pracy w celu dostosowania i utrzymania wspomnianych odchyleń. Okradanie modelu relacyjnego wymaga lepszego uzasadnienia niż to, co podałeś. Zobacz Przetwarzanie baz danych autorstwa Kroenke i Auer, aby uzyskać więcej informacji na temat komplikacji związanych z twoją odpowiedzią, ponieważ dotyczą one niewłaściwego wykorzystania atrybutów w relacjach.
Sage Gerard
29
Zakładasz, że nie konsultowałem się z administratorem w tej sprawie i nie rozumiem, co mówisz. Nie jestem na bieżąco z konsekwencjami tego faktu, zarówno dla małych systemów, jak i dalej, ale mówię, że się mylisz i że badania, na które wskazujesz, są stare i nie używają naszej aplikacji strategia. Jest to po prostu błędne, a problemy tkwią w kiepskiej implementacji tego procesu. Na przykład nie mówię, że mam tylko jeden model lub nie używam RDBMS, ale mówię mądrze, gdzie używasz RDBMS, a gdzie nie musisz.
Lewis Richard Phillip Cowles
6
To była najlepsza odpowiedź z mojego doświadczenia. Możesz używać RDBMS, ale przechowywać JSON tylko w określonych sytuacjach, jeśli wiesz, co robisz. W rzeczywistości często go używałem do tymczasowego przechowywania danych tablicowych w pamięci podręcznej i niektórych innych sytuacji, w których osiągasz szybszy wynik i mniej kodu. W rzeczywistości wiele projektów ma mieszane cechy.
Heroselohim
72

MySQL 5.7 obsługuje teraz natywny typ danych JSON podobny do MongoDB i innych magazynów danych dokumentów bez schematów:

Obsługa formatu JSON

Począwszy od MySQL 5.7.8, MySQL obsługuje natywny typ JSON. Wartości JSON nie są przechowywane jako ciągi znaków, zamiast tego używają wewnętrznego formatu binarnego, który umożliwia szybki dostęp do odczytu elementów dokumentu. Dokumenty JSON przechowywane w kolumnach JSON są automatycznie sprawdzane za każdym razem, gdy są wstawiane lub aktualizowane, a nieprawidłowy dokument powoduje błąd. Dokumenty JSON są normalizowane podczas tworzenia i można je porównać przy użyciu większości operatorów porównania, takich jak =, <, <=,>,> =, <>,! = I <=>; Aby uzyskać informacje o obsługiwanych operatorach, a także o pierwszeństwie i innych regułach, które MySQL przestrzega podczas porównywania wartości JSON, zobacz Porównanie i porządkowanie wartości JSON.

MySQL 5.7.8 wprowadza również szereg funkcji do pracy z wartościami JSON. Te funkcje obejmują te wymienione tutaj:

  1. Funkcje, które tworzą wartości JSON: JSON_ARRAY (), JSON_MERGE () i JSON_OBJECT (). Zobacz Sekcja 12.16.2, „Funkcje tworzące wartości JSON”.
  2. Funkcje wyszukujące wartości JSON: JSON_CONTAINS (), JSON_CONTAINS_PATH (), JSON_EXTRACT (), JSON_KEYS () i JSON_SEARCH (). Zobacz Sekcja 12.16.3, „Funkcje wyszukujące wartości JSON”.
  3. Funkcje modyfikujące wartości JSON: JSON_APPEND (), JSON_ARRAY_APPEND (), JSON_ARRAY_INSERT (), JSON_INSERT (), JSON_QUOTE (), JSON_REMOVE (), JSON_REPLACE (), JSON_SET () i JSON_UNOTE (). Zobacz Sekcja 12.16.4, „Funkcje modyfikujące wartości JSON”.
  4. Funkcje udostępniające informacje o wartościach JSON: JSON_DEPTH (), JSON_LENGTH (), JSON_TYPE () i JSON_VALID (). Zobacz Sekcja 12.16.5, „Funkcje zwracające atrybuty wartości JSON”.

W MySQL 5.7.9 i nowszych wersjach możesz użyć kolumny-> ścieżka jako skrótu dla JSON_EXTRACT (kolumna, ścieżka). Działa jak alias dla kolumny wszędzie tam, gdzie identyfikator kolumny może wystąpić w instrukcji SQL, w tym klauzule WHERE, ORDER BY i GROUP BY. Obejmuje to SELECT, UPDATE, DELETE, CREATE TABLE i inne instrukcje SQL. Lewa strona musi być identyfikatorem kolumny JSON (a nie aliasem). Po prawej stronie znajduje się cytowane w cudzysłowie wyrażenie ścieżki JSON, które jest oceniane na podstawie dokumentu JSON zwróconego jako wartość kolumny.

Aby uzyskać więcej informacji o -> i JSON_EXTRACT (), zobacz Sekcja 12.16.3, „Funkcje wyszukujące wartości JSON”. Aby uzyskać informacje na temat obsługi ścieżek JSON w MySQL 5.7, zobacz Wyszukiwanie i modyfikowanie wartości JSON. Zobacz także Dodatkowe indeksy i kolumny generowane wirtualnie.

Więcej informacji:

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

eecue
źródło
26

json nie jest niczym specjalnym, jeśli chodzi o przechowywanie, takie znaki jak

{, }, [, ], ', a-z, 0-9.... to naprawdę nic specjalnego i mogą być przechowywane jako tekst.

pierwszy problem, jaki będziesz mieć, jest taki

{profile_id: 22, nazwa użytkownika: „Robert”, hasło: „skhgeeht893htgn34ythg9er”}

który przechowywany w bazie danych nie jest tak prosty do aktualizacji, chyba że masz własne postępowanie i opracowałeś kod jsondecode dla mysql

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

Ponieważ nie możesz tego zrobić, musisz najpierw WYBRAĆ plik json, zdekodować go, zmienić, zaktualizować, więc teoretycznie równie dobrze możesz poświęcić więcej czasu na tworzenie odpowiedniej struktury bazy danych!

Używam json do przechowywania danych, ale tylko metadane, dane, które nie są często aktualizowane, niezwiązane z konkretnym użytkownikiem .. przykład, jeśli użytkownik dodaje post, a w tym poście dodaje obrazy źle analizuje obrazy i tworzy kciuki i następnie użyj adresów URL kciuków w formacie json.

RobertPitt
źródło
Czy wystarczy przechowywać ciąg json w bazie danych, gdy w ogóle go nie aktualizuję? Chcę tylko przeprowadzić normalne wyszukiwanie danych JSON przy użyciu LIKE. Widzę, że nawet Wordpress przechowuje metadane wtyczki jako ciąg json w bazie danych.
shasi kanth
@shasikanth, jeśli szukasz wartości w danych JSON, to szukałbym lepszego podejścia
Kirby
15

Aby zilustrować, jak trudno jest uzyskać dane JSON za pomocą zapytania, udostępnię zapytanie, które wykonałem, aby to obsłużyć.

Nie bierze pod uwagę tablic ani innych obiektów, tylko podstawowe typy danych. Powinieneś zmienić 4 wystąpienia kolumny na nazwę kolumny przechowującej JSON i zmienić 4 wystąpienia myfield na pole JSON, do którego chcesz uzyskać dostęp.

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'
Jorjon
źródło
5
Nie zapytałbyś jednak tej strony serwera. Oznaczałoby to zapisanie obiektu blob i przywrócenie go po stronie klienta. Wtedy po prostu użyjesz JS do odpytania. To było dawno temu :) Od tamtej pory przeniosłem się do MongoDB z tego powodu :) Głosuj za tym całkiem zgrabnym zapytaniem.
Oscar Godson
Myślę, że jest to kwestia tego, czy dana osoba ma regularnie uzyskiwać dostęp do danych JSON. Na przykład przenoszę nieistotne nagłówki do tablicy, analizuję do JSON, a następnie przechowuję. Kiedy pobiorę JSON (dla rzadkich żądań AJAX z dodatkowymi nagłówkami) po prostu ściągnę z MySQL, wczytuję JSON do tablicy i wyświetlę echo nagłówków. W przypadku jakichkolwiek bardziej intensywnych danych prawdopodobnie nie powinien być przechowywany jako JSON.
John
10

To naprawdę zależy od twojego przypadku użycia. Jeśli przechowujesz informacje, które nie mają absolutnie żadnej wartości w raportowaniu i nie będą odpytywane za pośrednictwem JOIN z innymi tabelami, może mieć sens przechowywanie danych w jednym polu tekstowym, zakodowanym jako JSON.

Może to znacznie uprościć model danych. Jednak, jak wspomniał RobertPitt, nie spodziewaj się, że będziesz w stanie połączyć te dane z innymi danymi, które zostały znormalizowane.

Phil LaNasa
źródło
2
Dokładnie moje myśli. Jeśli jego dane, które nigdy nie są łączone / przeszukiwane lub nawet rzadko aktualizowane, dlaczego nie użyć JSON w polu TEKST. Dobrym tego przykładem jest tabela produktów spożywczych, w której każdy artykuł spożywczy musiałby przechowywać informacje o wartości odżywczej. Wielkość porcji, proteiny, węglowodany, tłuszcz ogółem, tłuszcz nasycony, itp. Ale nie tylko, musisz zapisać wartość (0,2) i jednostkę, w której została zmierzona (g, oz, fl oz, ml). Biorąc pod uwagę, że są to dane, które (w zależności od tego, co robisz, jak sądzę) nie muszą być przeszukiwane, powiedziałbym, że 1 TEXT vs 16 int / varchar / enum kolumny to dobry kompromis.
Brad Moore
Dokładnie!!! Jest to przydatne, gdy musisz przechowywać zmienną i / lub nieznaną strukturę danych, której w ogóle nie planujesz filtrować za pomocą SQL. Dane są po prostu przechowywane tak, jak są, a ktoś inny (kod aplikacji) może znać strukturę i co z nią zrobić.
Delmo
9

To jest stare pytanie, ale nadal widzę je na górze wyników wyszukiwania Google, więc myślę, że sensowne byłoby dodanie nowej odpowiedzi 4 lata po zadaniu pytania.

Przede wszystkim istnieje lepsza obsługa przechowywania JSON w RDBMS. Możesz rozważyć przejście na PostgreSQL (chociaż MySQL obsługuje JSON od wersji 5.7.7). PostgreSQL używa bardzo podobnych poleceń SQL jak MySQL, z wyjątkiem tego, że obsługują więcej funkcji. Jedną z dodanych przez nich funkcji jest to, że zapewniają typ danych JSON i możesz teraz wysyłać zapytania do przechowywanych JSON. ( Trochę informacji na ten temat ) Jeśli nie tworzysz zapytania bezpośrednio w swoim programie, na przykład używając PDO w php lub elokwencji w Laravel, wszystko, co musisz zrobić, to po prostu zainstalować PostgreSQL na swoim serwerze i zmienić ustawienia połączenia z bazą danych. Nie musisz nawet zmieniać swojego kodu.

W większości przypadków, jak sugerowały inne odpowiedzi, przechowywanie danych jako JSON bezpośrednio w RDBMS nie jest dobrym pomysłem. Jest jednak pewien wyjątek. Jedna sytuacja, o której przychodzi mi do głowy, to pole ze zmienną liczbą powiązanych wpisów.

Na przykład, aby zapisać znacznik posta na blogu, zwykle będziesz potrzebować tabeli na post na blogu, tabeli znaczników i pasującej tabeli. Tak więc, gdy użytkownik chce edytować post i chcesz wyświetlić, który tag jest powiązany z tym postem, będziesz musiał odpytać 3 tabele. Spowoduje to znaczne obniżenie wydajności, jeśli pasująca tabela / tabela tagów jest długa.

Przechowując tagi jako JSON w tabeli postów na blogu, ta sama czynność wymaga przeszukiwania tylko jednej tabeli. Dzięki temu użytkownik będzie mógł szybciej edytować wpis na blogu, ale spowoduje to pogorszenie wydajności, jeśli chcesz sporządzić raport o tym, który post jest powiązany z tagiem, lub może wyszukiwać według tagu.

Możesz także spróbować cofnąć normalizację bazy danych. Duplikując dane i przechowując je w obie strony, możesz skorzystać z obu metod. Będziesz potrzebował tylko trochę więcej czasu na przechowywanie danych i więcej miejsca (co jest tanie w porównaniu z kosztem większej mocy obliczeniowej)

cytsunny
źródło
8

Powiedziałbym, że jedyne dwa powody, dla których warto to rozważyć, to:

  • wydajność po prostu nie jest wystarczająco dobra przy znormalizowanym podejściu
  • nie możesz łatwo modelować swoich szczególnie płynnych / elastycznych / zmieniających się danych

O swoim podejściu napisałem trochę tutaj:

Jakie problemy ze skalowalnością napotkałeś podczas korzystania z magazynu danych NoSQL?

(zobacz górną odpowiedź)

Nawet JSON nie był wystarczająco szybki, więc zastosowaliśmy podejście do niestandardowego formatu tekstu. Pracował / nadal działa dobrze dla nas.

Czy jest powód, dla którego nie używasz czegoś takiego jak MongoDB? (może być MySQL jest „wymagany”; po prostu ciekawy)

Brian
źródło
6

Wydaje mi się, że każdemu, kto odpowiada na to pytanie, w pewnym sensie brakuje jednej krytycznej kwestii, z wyjątkiem @deceze - użyj odpowiedniego narzędzia do pracy . Możesz zmusić relacyjną bazę danych do przechowywania prawie każdego rodzaju danych i możesz zmusić Mongo do obsługi danych relacyjnych, ale jakim kosztem? W końcu wprowadzasz złożoność na wszystkich poziomach rozwoju i konserwacji, od projektu schematu po kod aplikacji; nie wspominając o przeboju wydajności.

W 2014 roku mamy dostęp do wielu serwerów bazodanowych, które wyjątkowo dobrze radzą sobie z określonymi typami danych.

  • Mongo (przechowywanie dokumentów)
  • Redis (magazyn danych klucz-wartość)
  • MySQL / Maria / PostgreSQL / Oracle / etc (dane relacyjne)
  • CouchDB (JSON)

Jestem pewien, że brakowało mi innych, takich jak RabbirMQ i Cassandra. Chodzi mi o to, użyj odpowiedniego narzędzia do danych, które chcesz przechowywać.

Jeśli Twoja aplikacja wymaga przechowywania i pobierania różnych danych naprawdę, bardzo szybko (a kto tego nie robi), nie wahaj się korzystać z wielu źródeł danych dla aplikacji. Najpopularniejsze frameworki internetowe obsługują wiele źródeł danych (Rails, Django, Grails, Cake, Zend, itp.). Ta strategia ogranicza złożoność do jednego określonego obszaru aplikacji, ORM lub interfejsu źródła danych aplikacji.

CheddarMonkey
źródło
1
Twoim zdaniem RabbitMQ to serwer bazy danych czy coś w rodzaju? Powiedziałbym, że jest to oprogramowanie pośredniczące zorientowane na komunikaty z przyjemną funkcją trwałości, która pozwala nie tracić żadnych wiadomości, ale nic, na czym mógłbym zapisywać dane. Tylko moje dwa centy.
Osiriz,
@Osiriz: Masz rację. Prawdopodobnie nie powinienem był uwzględniać tego w tej dyskusji.
CheddarMonkey
5

Oto funkcja, która zapisuje / aktualizuje klucze tablicy JSON w kolumnie i inna funkcja, która pobiera wartości JSON. Te funkcje są tworzone przy założeniu, że nazwa kolumny przechowywania tablicy JSON to json . Używa PDO .

Funkcja zapisu / aktualizacji

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
 ));
}

gdzie $ uid to identyfikator użytkownika, $ key - klucz JSON do aktualizacji, a jego wartość to $ val .

Funkcja Get Value

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];
}

gdzie $ key to klucz tablicy JSON, z którego potrzebujemy wartości.

Subin
źródło
1
To kończy się niepowodzeniem w konfliktowych przypadkach, co się stanie, jeśli plik json, który właśnie przeczytałeś, zostanie zaktualizowany przez inny proces, a następnie zapiszesz json w bieżącym wątku, nadpisując go? Możesz potrzebować blokad, takich jak SELECT FOR UPDATElub wersjonowanie w danych JSON.
DhruvPathak,
@DhruvPathak Czy możesz zaktualizować odpowiedź za pomocą, SELECT FOR UPDATEaby była lepsza. Nie wiem, jak go używać.
Subin
3

Wczesne wsparcie dla przechowywania JSON w MySQL zostało dodane do wersji MySQL 5.7.7 JSON Labs ( pliki binarne Linux , źródło )! Wydaje się, że to wydanie wyrosło z serii funkcji zdefiniowanych przez użytkownika związanych z JSON, które zostały upublicznione w 2013 roku .

Ta rodząca się natywna obsługa JSON wydaje się zmierzać w bardzo pozytywnym kierunku, w tym walidacja JSON na INSERT, zoptymalizowanym formacie binarnym, w tym tablica przeglądowa w preambule, która pozwala funkcji JSN_EXTRACT na wykonywanie wyszukiwań binarnych zamiast analizowania przy każdym dostępie. Jest też cała masa nowych funkcji do obsługi i odpytywania określonych typów danych 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, powyższe jest doskonałym przykładem użycia tej nowej funkcji; wiele baz danych SQL ma już tabelę użytkownika i zamiast dokonywać niekończących się zmian schematu w celu dostosowania do zmieniającego się zestawu preferencji użytkownika, posiadanie pojedynczej kolumny JSON w pobliżu JOINjest idealne. Zwłaszcza, że ​​jest mało prawdopodobne, aby kiedykolwiek trzeba było zapytać o poszczególne elementy.

Chociaż to dopiero początek, zespół serwer MySQL robią wielkie zadanie komunikowanie zmian na tym blogu .

Rich Pollock
źródło
2

Uważam, że przechowywanie JSON w bazie danych mysql w rzeczywistości udaremnia cel używania RDBMS w takiej postaci, w jakiej ma być używany. Nie użyłbym go w żadnych danych, które w pewnym momencie zostałyby zmanipulowane lub zgłoszone, ponieważ nie tylko zwiększa złożoność, ale także może łatwo wpłynąć na wydajność w zależności od tego, w jaki sposób jest używany.

Byłem jednak ciekawy, czy ktoś inny wymyślił możliwy powód, aby to zrobić. Myślałem o zrobieniu wyjątku dla celów logowania. W moim przypadku chcę rejestrować żądania, które mają zmienną liczbę parametrów i błędów. W tej sytuacji chcę użyć tabel dla typu żądań, a samych żądań z ciągiem JSON o różnych uzyskanych wartościach.

W powyższej sytuacji żądania są rejestrowane i nigdy nie są przetwarzane ani indeksowane w polu ciągu JSON. JEDNAK, w bardziej złożonym środowisku, prawdopodobnie spróbuję użyć czegoś, co ma większe znaczenie dla tego typu danych i przechowywać je w tym systemie. Jak powiedzieli inni, to naprawdę zależy od tego, co próbujesz osiągnąć, ale przestrzeganie standardów zawsze pomaga w długowieczności i niezawodności!

znak
źródło
2

JSON jest poprawnym typem danych również w bazie danych PostgreSQL. Jednak baza danych MySQL nie obsługuje jeszcze oficjalnie formatu JSON. Ale to pieczenie: http://mysqlserverteam.com/json-labs-release-native-json-data-type-and-binary-format/

Zgadzam się również, że istnieje wiele ważnych przypadków, w których niektóre dane powinny być serializowane do łańcucha w bazie danych. Głównym powodem może być to, że nie są regularnie odpytywane, a jego własny schemat może się zmienić - nie chcesz zmieniać odpowiadającego mu schematu bazy danych. Drugim powodem jest to, że jeśli serializowany ciąg pochodzi bezpośrednio ze źródeł zewnętrznych, możesz nie chcieć analizować ich wszystkich i podawać do bazy danych za wszelką cenę, dopóki nie użyjesz żadnego. Będę więc czekał na nową wersję MySQL obsługującą JSON, ponieważ wtedy będzie łatwiej przełączać się między różnymi bazami danych.

Cherry Qianyu Liu
źródło
1

Używam json do nagrywania czegokolwiek dla projektu, w rzeczywistości używam trzech tabel! jeden dla danych w json, jeden dla indeksu wszystkich metadanych struktury json (każda meta jest kodowana przez unikalny identyfikator) i jeden dla użytkownika sesji, to wszystko. Benchmark nie może być określony ilościowo w tym wczesnym stanie kodu, ale na przykład byłem widokami użytkowników (sprzężenie wewnętrzne z indeksem), aby uzyskać kategorię (lub cokolwiek, jako użytkownik, ...) i było to bardzo wolne (bardzo, bardzo wolne , używany widok w mysql nie jest dobrym sposobem). Moduł wyszukiwania w tej strukturze może zrobić wszystko, co chcę, ale myślę, że mongodb będzie bardziej wydajny w tej koncepcji pełnego rekordu danych json. Na przykład używam widoków, aby utworzyć drzewo kategorii i menu nawigacyjne, mój Boże! tak wiele zapytań do zrobienia! sam apacz zniknął! i faktycznie na tej małej stronie używam php, który generuje drzewo i bułkę tartą, ekstrakcja danych jest wykonywana przez moduł wyszukiwania (który używa tylko indeksu), tabela danych służy tylko do aktualizacji. Jeśli chcę, mogę zniszczyć wszystkie indeksy i zregenerować je z każdym danymi i wykonać odwrotną pracę, aby na przykład zniszczyć wszystkie dane (json) i ponownie je wygenerować tylko z tabelą indeksów. Mój projekt jest młody, działa pod php i mysql, ale czasami myślę, że używanie node js i mongodb będzie bardziej wydajne w tym projekcie.

Użyj json, jeśli myślisz, że możesz to zrobić, po prostu zrób to, ponieważ możesz! i zapomnij o tym, jeśli to był błąd; spróbuj dokonać dobrego lub złego wyboru, ale spróbuj!

Niska

francuski użytkownik

Niska
źródło
1
Nie rozumiem. Nie mówię po angielsku natywnie, ale radziłbym używać kropek (.), Przecinków (,) i akapitów (klawisz Enter), aby uporządkować swoje pomysły. Potem tylko wtedy spróbuj uporządkować bazę danych ;-)
Diego Jancic
Masz rację, w rzeczywistości niejasna odpowiedź musi być bardziej wyraźna, pokazując przykład. Ale jeśli mysql można zastąpić mongoDB, bardziej efektywne będzie użycie json (jako natywnego dla mongodb), jeśli mysql jest obowiązkowe, ok, spróbujmy ponownie za kilka dni!
niski
1

Wiem, że jest to naprawdę późno, ale miałem podobną sytuację, w której zastosowałem podejście hybrydowe polegające na utrzymywaniu standardów RDBMS polegających na normalizowaniu tabel do pewnego punktu, a następnie przechowywaniu danych w JSON jako wartości tekstowej poza tym punktem. Na przykład przechowuję dane w 4 tabelach zgodnie z zasadami normalizacji RDBMS. Jednak w czwartej tabeli, aby dostosować dynamiczny schemat, przechowuję dane w formacie JSON. Za każdym razem, gdy chcę pobrać dane, pobieram dane JSON, analizuję je i wyświetlam w Javie. Jak dotąd działało to dla mnie i zapewniam, że nadal jestem w stanie indeksować pola, które przekształcam w dane JSON w tabeli w znormalizowany sposób przy użyciu ETL. Gwarantuje to, że podczas pracy z aplikacją użytkownik napotyka minimalne opóźnienia, a pola są przekształcane do formatu przyjaznego dla RDBMS do analizy danych itp.

prashant
źródło
0

Możesz użyć tego sedna: https://gist.github.com/AminaG/33d90cb99c26298c48f670b8ffac39c3

Po zainstalowaniu go na serwerze (potrzebujesz tylko uprawnień roota, a nie super), możesz zrobić coś takiego:

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

To zwróci a 2 . Możesz zwrócić wszystko wewnątrz JSON, używając tego. Dobra część jest taka, że ​​obsługuje MySQL 5.1,5.2,5.6. I nie musisz instalować żadnych plików binarnych na serwerze.

Oparty na starym projekcie common-schema, ale nadal działa dzisiaj https://code.google.com/archive/p/common-schema/

Aminadav Glickshtein
źródło
sednem