W MySQL 5.7 dodano nowy typ danych do przechowywania danych JSON w tabelach MySQL . Będzie to oczywiście wielka zmiana w MySQL. Wymienili kilka korzyści
Walidacja dokumentów - w kolumnie JSON można przechowywać tylko prawidłowe dokumenty JSON, dzięki czemu uzyskujesz automatyczną weryfikację danych.
Wydajny dostęp - co ważniejsze, gdy przechowujesz dokument JSON w kolumnie JSON, nie jest on przechowywany jako zwykła wartość tekstowa. Zamiast tego jest przechowywany w zoptymalizowanym formacie binarnym, który umożliwia szybszy dostęp do składowych obiektów i elementów tablicy.
Wydajność - popraw wydajność zapytań, tworząc indeksy wartości w kolumnach JSON. Można to osiągnąć za pomocą „indeksów funkcjonalnych” w wirtualnych kolumnach.
Wygoda - dodatkowa składnia wbudowana w kolumny JSON sprawia, że integracja zapytań dokumentów w SQL jest bardzo naturalna. Na przykład (features.feature to kolumna JSON):
SELECT feature->"$.properties.STREET" AS property_street FROM features WHERE id = 121254;
ŁAŁ ! zawierają świetne funkcje. Teraz łatwiej jest manipulować danymi. Teraz możliwe jest przechowywanie bardziej złożonych danych w kolumnie. Więc MySQL jest teraz wzbogacony o NoSQL.
Teraz mogę sobie wyobrazić zapytanie o dane JSON w stylu
SELECT * FROM t1
WHERE JSON_EXTRACT(data,"$.series") IN
(
SELECT JSON_EXTRACT(data,"$.inverted")
FROM t1 | {"series": 3, "inverted": 8}
WHERE JSON_EXTRACT(data,"$.inverted")<4 );
Czy mogę więc przechowywać ogromne, małe relacje w kilku kolumnach json? Czy to jest dobre? Czy to łamie normalizację. Jeśli jest to możliwe, myślę, że będzie działać jak NoSQL w kolumnie MySQL . Naprawdę chcę dowiedzieć się więcej o tej funkcji. Plusy i minusy typu danych MySQL JSON.
Now it is possible to store more complex data in column
. UważajOdpowiedzi:
Użycie kolumny wewnątrz wyrażenia lub funkcji, takiej jak ta, niweczy wszelkie szanse, że zapytanie użyje indeksu, aby zoptymalizować zapytanie. Zapytanie pokazane powyżej jest zmuszone wykonać skanowanie tabeli.
Twierdzenie o „skutecznym dostępie” jest mylące. Oznacza to, że po sprawdzeniu przez zapytanie wiersza z dokumentem JSON może wyodrębnić pole bez konieczności analizowania tekstu składni JSON. Ale wyszukiwanie wierszy nadal wymaga skanowania tabeli. Innymi słowy, zapytanie musi zbadać każdy wiersz.
Analogicznie, jeśli wyszukuję w książce telefonicznej osoby o imieniu „Bill”, nadal muszę czytać każdą stronę w książce telefonicznej, nawet jeśli imiona zostały podświetlone, aby ich odnalezienie było nieco szybsze.
MySQL 5.7 umożliwia zdefiniowanie wirtualnej kolumny w tabeli, a następnie utworzenie indeksu na wirtualnej kolumnie.
Następnie, jeśli zapytasz o wirtualną kolumnę, może ona użyć indeksu i uniknąć skanowania tabeli.
To fajne, ale mija się z celem używania JSON. Atrakcyjną częścią korzystania z formatu JSON jest to, że umożliwia on dodawanie nowych atrybutów bez konieczności wykonywania ALTER TABLE. Ale okazuje się, że i tak musisz zdefiniować dodatkową (wirtualną) kolumnę, jeśli chcesz przeszukiwać pola JSON za pomocą indeksu.
Ale nie musisz definiować wirtualnych kolumn i indeksów dla każdego pola w dokumencie JSON - tylko te, które chcesz przeszukiwać lub sortować. Mogą istnieć inne atrybuty w formacie JSON, które wystarczy wyodrębnić z listy wyboru, jak poniżej:
Generalnie powiedziałbym, że jest to najlepszy sposób wykorzystania JSON w MySQL. Tylko na liście wyboru.
Gdy odwołujesz się do kolumn w innych klauzulach (JOIN, WHERE, GROUP BY, HAVING, ORDER BY), bardziej wydajne jest użycie konwencjonalnych kolumn, a nie pól w dokumentach JSON.
Przedstawiłem wykład pt. Jak używać JSON w MySQL Wrong na konferencji Percona Live w kwietniu 2018 r. Zaktualizuję i powtórzę wykład na Oracle Code One jesienią.
Istnieją inne problemy z JSON. Na przykład w moich testach wymagał 2-3 razy więcej miejsca na przechowywanie dokumentów JSON w porównaniu do konwencjonalnych kolumn przechowujących te same dane.
MySQL agresywnie promuje swoje nowe możliwości JSON, głównie w celu zniechęcenia ludzi do migracji do MongoDB. Ale przechowywanie danych zorientowane na dokumenty, takie jak MongoDB, jest zasadniczo nierelacyjnym sposobem organizowania danych. Różni się od relacyjnego. Nie mówię, że jedna jest lepsza od drugiej, to po prostu inna technika, dostosowana do różnych typów zapytań.
Należy zdecydować się na użycie formatu JSON, gdy JSON zwiększa wydajność zapytań.
Nie wybieraj technologii tylko dlatego, że jest nowa lub ze względu na modę.
Edycja: implementacja kolumny wirtualnej w MySQL powinna używać indeksu, jeśli klauzula WHERE używa dokładnie tego samego wyrażenia, co definicja kolumny wirtualnej. Oznacza to, że następujące osoby powinny używać indeksu w kolumnie wirtualnej, ponieważ kolumna wirtualna jest zdefiniowana
AS (JSON_EXTRACT(data,"$.series"))
Z wyjątkiem tego, że podczas testowania tej funkcji odkryłem, że NIE działa ona z jakiegoś powodu, jeśli wyrażenie jest funkcją wyodrębniania JSON. Działa z innymi typami wyrażeń, ale nie z funkcjami JSON.
źródło
JOIN
,WHERE
lub innych klauzul. Po prostu pobierz kolumnę JSON z listy wyboru.Poniższe z MySQL 5.7 przywraca sexy z JSON brzmi dla mnie dobrze:
...
Zwróć uwagę na język dotyczący walidacji dokumentów, ponieważ jest to ważny czynnik. Wydaje mi się, że należy przeprowadzić serię testów, aby porównać oba podejścia. Te dwie rzeczy:
W sieci są tylko płytkie udostępnienia slajdów na temat mysql / json / wydajności z tego, co widzę.
Być może Twój post może być dla niego centrum. A może wydajność jest następstwem przemyślenia, nie jestem pewien, i jesteś po prostu podekscytowany, aby nie tworzyć wielu tabel.
źródło
[citation required]
czy porównałeś ten dysk z pamięcią RAM?Niedawno wpadłem w ten problem i podsumowuję następujące doświadczenia:
1, nie ma sposobu na rozwiązanie wszystkich pytań. 2, powinieneś poprawnie używać JSON.
Jeden przypadek:
Mam tabelę o nazwie:,
CustomField
która musi zawierać dwie kolumny:name
,fields
.name
jest zlokalizowanym ciągiem, jego zawartość powinna wyglądać następująco:I
fields
powinno wyglądać tak:Jak widać, zarówno
name
plikfields
może być zapisany jako JSON, i to działa!Jeśli jednak używam
name
bardzo często do przeszukiwania tej tabeli, co powinienem zrobić? UżyjJSON_CONTAINS
,JSON_EXTRACT
...? Oczywiście zapisywanie go jako JSON nie jest już dobrym pomysłem, powinniśmy zapisać go w niezależnej tabeli:CustomFieldName
.Z powyższego przypadku myślę, że powinieneś pamiętać o następujących pomysłach:
Dzięki
źródło
Z mojego doświadczenia wynika, że implementacja JSON przynajmniej w MySql 5.7 nie jest zbyt przydatna ze względu na słabą wydajność. Cóż, nie jest tak źle, jeśli chodzi o odczytywanie danych i sprawdzanie poprawności. Jednak modyfikacja JSON jest 10-20 razy wolniejsza w MySql niż w Pythonie czy PHP. Wyobraźmy sobie bardzo prosty JSON:
Załóżmy, że musimy przekonwertować to na coś takiego:
Możesz stworzyć prosty skrypt w Pythonie lub PHP, który wybierze wszystkie wiersze i zaktualizuje je jeden po drugim. Nie jesteś zmuszony do wykonania jednej dużej transakcji, więc inne aplikacje będą mogły korzystać z tabeli równolegle. Oczywiście, jeśli chcesz, możesz też dokonać jednej ogromnej transakcji, dzięki czemu uzyskasz gwarancję, że MySql wykona „wszystko albo nic”, ale inne aplikacje najprawdopodobniej nie będą w stanie korzystać z bazy danych podczas wykonywania transakcji.
Mam tabelę 40 milionów wierszy, a skrypt Pythona aktualizuje ją w ciągu 3-4 godzin.
Teraz mamy MySql JSON, więc nie potrzebujemy już Pythona ani PHP, możemy zrobić coś takiego:
Wygląda prosto i doskonale. Jednak jego prędkość jest 10-20 razy wolniejsza niż wersja Pythona i jest to pojedyncza transakcja, więc inne aplikacje nie mogą równolegle modyfikować danych tabeli.
Tak więc, jeśli chcemy po prostu zduplikować klucz JSON w tabeli 40 milionów wierszy, nie musimy w ogóle używać tabeli przez 30-40 godzin. To nie ma sensu.
Jeśli chodzi o czytanie danych, z mojego doświadczenia wynika, że bezpośredni dostęp do pola JSON przez
JSON_EXTRACT
inWHERE
jest również wyjątkowo wolny (znacznie wolniejszy niż wTEXT
przypadkuLIKE
nieindeksowanej kolumny). Wirtualne kolumny generowane działają znacznie szybciej, jednak jeśli znamy wcześniej strukturę danych, nie potrzebujemy JSON, możemy zamiast tego użyć tradycyjnych kolumn. Kiedy używamy JSON tam, gdzie jest to naprawdę przydatne, tj. Gdy struktura danych jest nieznana lub często się zmienia (na przykład niestandardowe ustawienia wtyczek), regularne tworzenie wirtualnych kolumn dla ewentualnych nowych kolumn nie wygląda na dobry pomysł.Python i PHP sprawiają, że walidacja JSON jest jak urok, więc wątpliwe jest, czy w ogóle potrzebujemy walidacji JSON po stronie MySql. Dlaczego by nie sprawdzić poprawności XML, dokumentów Microsoft Office lub sprawdzić pisownię? ;)
źródło