Verileri MySQL'de JSON olarak Depolama


121

Bunun yapılmaması gereken bir şey olduğunu düşündüm. Ve ben de bunu hiç yapmadım. Sonra FriendFeed'in bunu yaptığını ve DB ölçeğini daha iyi hale getirdiğini ve gecikmeyi azalttığını gördüm. Bunu yapmalı mıyım merak ediyorum. Ve eğer öyleyse, bunu yapmanın doğru yolu nedir?

Temel olarak, her şeyi MySQL'de bir CouchDB DB türü olarak saklamayı öğrenmek için iyi bir yer neresi? Her şeyi JSON olarak depolamak daha kolay ve daha hızlı olacak gibi görünüyor (derleme değil, daha az gecikme).

Ayrıca, DB'de JSON olarak depolanan şeyleri düzenlemek, silmek vb. Kolay mı?


Referans olarak, bunun FriendFeed'in MySQL'de
dimo414

10
MySQL 5.7 artık yerel bir JSON veri deposunu destekliyor.
eecue

Yanıtlar:


57

CouchDB ve MySQL çok farklı iki canavar. JSON, CouchDB'de malzeme depolamanın yerel yoludur. MySQL'de yapabileceğiniz en iyi şey JSON verilerini tek bir alanda metin olarak depolamaktır. Bu, onu bir RDBMS'de saklama amacını tamamen ortadan kaldırır ve her veritabanı işlemini büyük ölçüde karmaşıklaştırır.

Yapma.

Bunu söyledikten sonra, FriendFeed , MySQL'in üstünde son derece özel bir şema kullanıyor gibiydi . Bu gerçekten tam olarak ne depolamak istediğinize bağlıdır, bir veritabanı sisteminin nasıl kötüye kullanılacağına dair kesin bir cevap yoktur, bu yüzden sizin için mantıklıdır. Makalenin çok eski olduğu ve Mongo ve Couch'a karşı ana sebeplerinin olgunlaşmamışlık olduğu göz önüne alındığında, MySQL sizin için kesmezse bu ikisini yeniden değerlendiririm. Şimdiye kadar çok büyümeleri gerekirdi.


3
Evet, Mongo'ya bakıyorum ve php'nin bunun için bir uzantısı var ve DB işlemleri için gerçek sözdizimi MySQL'den daha kolay görünüyor ve genel olarak onunla çalışmak couchDB'den daha kolay görünüyor. Teşekkürler, sanırım MongoDB ile gideceğim :)
Oscar Godson

68
JSON blob'larını bir RDBMS'de depolamak için kesinlikle geçerli durumlar vardır. Bazı senaryolarda oldukça sık görülen, bu verileri sorgulamaya gerek kalmadan yalnızca JSON verilerinin opak bloblarını depolamak ve almak istiyorsanız, bunu çok iyi yapabilirsiniz.
markus

9
@markus Bunu web sitelerimden birinde yapıyorum, özellikle MySQL sorgularında doğrudan aranmayan, ancak formları görüntülerken kullanılan (bir tablo görünümünden veya doğrudan bir bağlantı yoluyla) karmaşık bir formun alanlarında. Muhtemelen ideal değildir, ancak kesinlikle uygulamayı çok daha hızlı hale getirir ve aşırı miktarda tablo veya tablo sütununa olan ihtiyacı ortadan kaldırır.
Nick Bedford

1
Uygulamanız için hem RDBMS hem de belge türü depolamaya sahip olmak istiyorsanız, bu iyi bir yaklaşımdır, bu nedenle birden çok veritabanını yönetmek zorunda kalmazsınız.
rjarmstrong

5
Bu oldukça kısa süreli bir tavsiye, belki de yığın değişiminde çok fazla zaman harcayan biri tarafından? Saklamak istediğim 100 alana sahip bir kaydım olduğunda ve alanların yalnızca 3 veya 4'ünde arama yapmam gerektiğinde, 100 alanlı bir tablo oluşturmak anlamsızdır. JSON'da 1 alanda depolanan tüm adres defteriyle bir müşteri kaydını saklayabilir ve kayıtları aramak için kullanmak üzere müşteri kimliğini, soyadını, şirketi diğer alanlar olarak ekleyebilirsiniz. Bu bir. büyük zaman tasarrufu.
Danial

102

Yorum yapan herkes buna yanlış açıdan geliyor gibi görünüyor, JSON kodunu PHP aracılığıyla ilişkisel bir DB'de saklamak sorun değil ve aslında bunun gibi karmaşık verileri yüklemek ve görüntülemek daha hızlı olacak, ancak aşağıdaki gibi tasarım düşüncelerine sahip olacaksınız. arama, indeksleme vb.

Bunu yapmanın en iyi yolu, hibrit veri kullanmaktır, örneğin tarih saatine göre arama yapmanız gerekiyorsa MySQL (performans ayarlı) PHP'den çok daha hızlı olacaktır ve mekanların mesafesini aramak gibi bir şey için MySQL de çok olmalıdır. daha hızlı (erişilemeyen aramaya dikkat edin). Aramanız gerekmeyen veriler, JSON, BLOB veya gerçekten gerekli gördüğünüz herhangi bir formatta saklanabilir.

Erişmeniz gereken veriler çok kolay bir şekilde JSON olarak depolanır, örneğin basit bir kasa başına fatura sistemi. RDBMS'den çok fazla yararlanmazlar ve doğru HTML form yapısına sahipseniz JSON'da sadece json_encoding ($ _ POST ['entires']) ile depolanabilirler.

MongoDB'yi kullanmaktan mutlu olduğunuz için mutluyum ve umarım size iyi hizmet vermeye devam eder, ancak MySQL'in her zaman gözünüzün dışında kalacağını düşünmeyin, çünkü uygulamanızın karmaşıklığı arttıkça bir RDBMS'ye ihtiyaç duyabilirsiniz. bazı işlevler ve özellikler (yalnızca arşivlenmiş verilerin veya iş raporlamasının kullanımdan kaldırılması için olsa bile)


8
-1 için "PHP aracılığıyla JSON kodunu ilişkisel bir DB'de saklamak iyidir" - JSON'u (bütün bir varlığı atomik olmayan veri olarak temsil edebilir) tek bir alanda depolamak ilişkisel modeli ihlal eder ve 1NF'yi önler. Ayrıca, sizi destekleyecek ölçümler olmadan performansla ilgili kapsamlı iddialarda bulunmayın.
Sage Gerard

80
Bahsedildiği gibi, ne sakladığınıza bağlıdır, yani bir fatura için gerçekten her girişi ayrı ayrı saklamanız gerekiyor mu? HAYIR, yorumunuz çok şey bildiğiniz gibi karşınıza çıkıyor ama 1NF her alan için değil ya da BLOB ve metin türleri olmayacak ... bu bir üretim sistemi için tamamen saçmalık, sadece aramanız gereken şeyi optimize etmeniz gerekiyor yani tarihler, anahtarlar ve bazı veriler üzerinde dizin oluşturma. Her şeyi JSON olarak sakla demedim, sorununuzu çözmeye yardımcı olacaksa bazı verileri JSON olarak saklayın dedim.
Lewis Richard Phillip Cowles

2
Söyledikleriniz mümkün ve uygundur, ancak iyi oluşturulmuş ilişkilerden sapmak, söz konusu sapmaları dengelemek ve sürdürmek için daha fazla iş yapmak anlamına gelir. İlişkisel modeli ayıplamak, sağladığınızdan daha iyi gerekçelendirmeye ihtiyaç duyar. İlişkilerdeki özniteliklerin kötüye kullanımına değindikleri için cevabınızla ilgili karmaşıklıklar hakkında daha fazla bilgi için Kroenke ve Auer tarafından Veritabanı İşleme konusuna bakın.
Sage Gerard

29
Bu konuda bir DBA'ya danışmadığımı ve ne dediğinizi anlamadığımı varsayıyorsunuz. Hem küçük sistemler hem de daha ileride bunun için ne anlama geldiği konusunda döngüde tutulmuyorum, ancak söylüyorum, yanılıyorsunuz ve işaret ettiğiniz araştırma eski ve uygulamamızı kullanmıyor. stratejisi. Bu tamamen yanlıştır ve problemler bu sürecin kötü uygulamalarında yanar. Örneğin, sadece bir modeliniz var ya da bir RDBMS kullanmıyorum demiyorum, RDBMS'yi nerede kullandığınız ve nerede ihtiyacınız olmadığı konusunda akıllı olun diyorum.
Lewis Richard Phillip Cowles

6
Deneyimlerime göre en iyi cevap buydu. RDBMS'yi kullanabilir, ancak JSON'u yalnızca ne yaptığınızı biliyorsanız belirli durumlarda depolayabilirsiniz. Aslında bunu, dizi verilerinin geçici olarak önbellekte depolanması ve daha hızlı sonuç ve daha az kod elde ettiğiniz diğer bazı durumlar için çok kullandım. Gerçekte birçok projenin bazı karışık özellikleri vardır.
Heroselohim

72

MySQL 5.7 Artık MongoDB'ye ve diğer şemasız belge veri depolarına benzer bir yerel JSON veri türünü destekliyor:

JSON desteği

MySQL 5.7.8 ile başlayan MySQL, yerel bir JSON türünü destekler. JSON değerleri dizeler olarak saklanmaz, bunun yerine belge öğelerine hızlı okuma erişimine izin veren dahili bir ikili biçim kullanır. JSON sütunlarında depolanan JSON belgeleri, her eklendiğinde veya güncellendiğinde otomatik olarak doğrulanır ve geçersiz bir belge hata oluşturur. JSON belgeleri oluşturulduktan sonra normalleştirilir ve =, <, <=,>,> =, <>,! = Ve <=> gibi çoğu karşılaştırma operatörü kullanılarak karşılaştırılabilir; MySQL'in JSON değerlerini karşılaştırırken izlediği öncelik ve diğer kuralların yanı sıra desteklenen işleçler hakkında bilgi için bkz. JSON Değerlerinin Karşılaştırılması ve Sıralanması.

MySQL 5.7.8 ayrıca JSON değerleriyle çalışmak için bir dizi işlev sunar. Bu işlevler, burada listelenenleri içerir:

  1. JSON değerleri oluşturan işlevler: JSON_ARRAY (), JSON_MERGE () ve JSON_OBJECT (). Bkz. Bölüm 12.16.2, "JSON Değerleri Oluşturan İşlevler".
  2. JSON değerlerini arayan işlevler: JSON_CONTAINS (), JSON_CONTAINS_PATH (), JSON_EXTRACT (), JSON_KEYS () ve JSON_SEARCH (). Bkz. Bölüm 12.16.3, "JSON Değerlerini Arayan İşlevler".
  3. JSON değerlerini değiştiren işlevler: JSON_APPEND (), JSON_ARRAY_APPEND (), JSON_ARRAY_INSERT (), JSON_INSERT (), JSON_QUOTE (), JSON_REMOVE (), JSON_REPLACE (), JSON_SET (), ve JSON_UN. Bkz. Bölüm 12.16.4, "JSON Değerlerini Değiştiren İşlevler".
  4. JSON değerleri hakkında bilgi sağlayan işlevler: JSON_DEPTH (), JSON_LENGTH (), JSON_TYPE () ve JSON_VALID (). Bkz. Bölüm 12.16.5, "JSON Değeri Özniteliklerini Döndüren İşlevler".

MySQL 5.7.9 ve sonraki sürümlerde, JSON_EXTRACT (sütun, yol) için bir kısaltma olarak sütun-> yolunu kullanabilirsiniz. Bu, WHERE, ORDER BY ve GROUP BY cümleleri de dahil olmak üzere, bir sütun tanımlayıcısının bir SQL deyiminde bulunabildiği her yerde bir sütun için bir diğer ad olarak çalışır. Buna SELECT, UPDATE, DELETE, CREATE TABLE ve diğer SQL ifadeleri dahildir. Sol taraf bir JSON sütun tanımlayıcısı olmalıdır (takma ad olmamalıdır). Sağ taraf, sütun değeri olarak döndürülen JSON belgesine göre değerlendirilen alıntılanmış bir JSON yol ifadesidir.

-> ve JSON_EXTRACT () hakkında daha fazla bilgi için Bölüm 12.16.3, “JSON Değerlerini Arayan İşlevler” e bakın. MySQL 5.7'de JSON yolu desteği hakkında bilgi için bkz. JSON Değerlerini Arama ve Değiştirme. Ayrıca bkz. İkincil Dizinler ve Sanal Olarak Oluşturulan Sütunlar.

Daha fazla bilgi:

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


26

json karakterleri, depolama söz konusu olduğunda özel bir şey değildir.

{, }, [, ], ', a-z, 0-9.... gerçekten özel bir şey değildir ve metin olarak saklanabilir.

sahip olacağın ilk problem bu

{profile_id: 22, kullanıcı adı: 'Robert', şifre: 'skhgeeht893htgn34ythg9er'}

bir veritabanında depolananlar, kendi işleminize sahip olmadığınız ve mysql için bir jsondecode geliştirmediyseniz, güncellemek o kadar kolay değildir.

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

Bunu yapamayacağınız için, önce json'u SEÇİN, Kodunu çözün, değiştirin, güncelleyin, böylece teoride uygun bir veritabanı yapısı oluşturmak için daha fazla zaman harcayabilirsiniz!

Verileri depolamak için json kullanıyorum, ancak yalnızca Meta Verileri, sık sık güncellenmeyen, kullanıcıya özgü verilerle ilgili olmayan verileri kullanıyorum. Örneğin, bir kullanıcı bir gönderi eklerse ve bu gönderiye görüntüler eklerse görüntüleri ayrıştırır ve küçük resimler oluşturur ve daha sonra başparmak url'lerini json biçiminde kullanın.


Hiç güncellemediğimde json dizesini veritabanında depolamak yeterince iyi mi? Sadece LIKE kullanarak json verileri üzerinde normal bir arama yapmak istiyorum. Wordpress'in bile eklenti meta verilerini veritabanında json dizesi olarak sakladığını görüyorum.
shasi kanth

@shasikanth, JSON verilerinde değer arıyorsanız, o zaman daha iyi bir yaklaşım ararım
Kirby

15

JSON verilerini bir sorgu kullanarak almanın ne kadar zor olduğunu göstermek için, bunu işlemek için yaptığım sorguyu paylaşacağım.

Dizileri veya diğer nesneleri hesaba katmaz, sadece temel veri türlerini hesaba katar. 4 sütun örneğini JSON'u depolayan sütun adına değiştirmeli ve alanımın 4 örneğini erişmek istediğiniz JSON alanına değiştirmelisiniz.

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'

5
Bu sunucu tarafını sorgulamazsın. Bu, bir blob depolamak ve onu istemci tarafında geri almak olacaktır. Daha sonra sorgulamak için JS'yi kullanırsınız. Bu uzun zaman önceydi tho :) O zamandan beri bu şeyler için MongoDB'ye taşındım :) Bu oldukça kaygan sorgu için oy verin tho.
Oscar Godson

Kişinin bu JSON verilerine düzenli olarak erişip erişemeyeceği sorusu bence. Örneğin, gerekli olmayan başlıkları bir diziye taşıyorum, JSON'a ayrıştırıyorum ve sonra depoluyorum. JSON'u aldığımda (nadir ekstra başlıklar AJAX isteği için) MySQL'den çekeceğim, JSON'u bir diziye okuyacağım ve başlıkları yankılayacağım. Daha fazla veri gerektiren herhangi bir şey için muhtemelen JSON olarak depolanmamalıdır.
John

10

Gerçekten kullanım durumunuza bağlıdır. Raporlamada kesinlikle hiçbir değeri olmayan ve JOIN'ler aracılığıyla diğer tablolarla sorgulanmayacak bilgileri depoluyorsanız, verilerinizi JSON olarak kodlanmış tek bir metin alanında depolamanız sizin için mantıklı olabilir.

Bu, veri modelinizi büyük ölçüde basitleştirebilir. Ancak, RobertPitt'in bahsettiği gibi, bu verileri normalleştirilmiş diğer verilerle birleştirmeyi beklemeyin.


2
Benim düşüncelerim tam. Hiçbir zaman birleştirilmeyen / aranmayan veya nadiren güncellenen verileri ise, neden bir METİN alanında json kullanmıyorsunuz? Buna güzel bir örnek, her bir gıda maddesinin beslenme bilgilerini saklaması gereken bir yiyecek maddesi tablosudur. Porsiyon büyüklüğü, protien, karbonhidrat, yağ toplamı, doymuş yağ, vb. Ancak sadece bu değil, değeri (0.2) ve ölçülen birimi (g, oz, fl oz, ml) olarak saklamanız gerekecek. (Sanırım ne yaptığınıza bağlı olarak) aranması gerekmeyen veriler olduğu düşünüldüğünde, 1 TEXT - 16 int / varchar / enum sütunlarının iyi bir değiş tokuş olduğunu söyleyebilirim.
Brad Moore

Kesinlikle!!! SQL ile filtrelemeyi planlamadığınız değişken ve / veya bilinmeyen veri yapısını depolamanız gerektiğinde kullanışlıdır. Veriler basitçe olduğu gibi saklanır ve bir başkası (uygulama kodu) yapıyı ve onunla ne yapılacağını bilebilir.
Delmo

9

Bu eski bir soru, ancak bunu hala Google'ın arama sonuçlarının en üstünde görebiliyorum, bu yüzden soru sorulduktan 4 yıl sonra yeni bir cevap eklemenin anlamlı olacağını tahmin ediyorum.

Her şeyden önce, JSON'u RDBMS'de depolamak için daha iyi destek var. PostgreSQL'e geçmeyi düşünebilirsiniz (MySQL, JSON'u v5.7.7'den beri desteklemesine rağmen). PostgreSQL, daha fazla işlevi desteklemeleri dışında MySQL ile çok benzer SQL komutları kullanır. Ekledikleri işlevlerden biri, JSON veri türü sağlamaları ve artık depolanan JSON'u sorgulayabilmenizdir. (Buna bazı referanslar ) Sorguyu doğrudan programınızda oluşturmuyorsanız, örneğin, php'de PDO veya Laravel'de anlamlı kullanarak, tek yapmanız gereken PostgreSQL'i sunucunuza kurmak ve veritabanı bağlantı ayarlarını değiştirmek. Kodunuzu değiştirmenize bile gerek yok.

Çoğu zaman, diğer yanıtların önerdiği gibi, verileri doğrudan RDBMS'de JSON olarak depolamak iyi bir fikir değildir. Yine de bazı istisnalar var. Aklıma gelen bir durum, değişken sayıda bağlantılı girişe sahip bir alandır.

Örneğin, bir blog gönderisinin etiketini depolamak için, normalde blog gönderisi için bir tabloya, bir etiket tablosuna ve eşleşen bir tabloya ihtiyacınız olacaktır. Bu nedenle, kullanıcı bir gönderiyi düzenlemek istediğinde ve siz o gönderiyle ilgili olan etiketi görüntülemeniz gerektiğinde, 3 tabloyu sorgulamanız gerekecektir. Bu, eşleşen tablonuz / etiket tablonuz uzunsa performansa çok zarar verir.

Etiketleri blog yayını tablosunda JSON olarak depolayarak, aynı işlem yalnızca tek bir tablo araması gerektirir. Böylece kullanıcı, blog gönderisinin daha hızlı düzenlenmesini görebilecektir, ancak hangi gönderinin bir etikete bağlı olduğu hakkında bir rapor oluşturmak veya belki etikete göre arama yapmak istiyorsanız bu performansa zarar verecektir.

Veritabanını normalleştirmeyi de deneyebilirsiniz. Verileri çoğaltarak ve verileri her iki şekilde depolayarak, her iki yöntemden de yararlanabilirsiniz. Verilerinizi depolamak için biraz daha fazla zamana ve daha fazla depolama alanına ihtiyacınız olacak (bu, daha fazla bilgi işlem gücünün maliyetine kıyasla ucuzdur)


8

Bunu düşünmek için iki nedenin olduğunu söyleyebilirim:

  • performans normalleştirilmiş bir yaklaşımla yeterince iyi değil
  • özellikle akıcı / esnek / değişen verilerinizi kolayca modelleyemezsiniz

Burada kendi yaklaşımım hakkında biraz yazdım:

NoSQL veri deposu kullanırken hangi ölçeklenebilirlik sorunlarıyla karşılaştınız?

(üst cevaba bakın)

JSON bile yeterince hızlı değildi, bu yüzden özel bir metin biçimi yaklaşımı kullandık. Bizim için iyi çalıştı / çalışmaya devam ediyor.

MongoDB gibi bir şey kullanmamanın bir nedeni var mı? (MySQL "gerekli" olabilir; sadece merak)


6

Bana öyle geliyor ki, bu soruyu yanıtlayan herkes, @deceze dışında bir tür kritik sorunu gözden kaçırıyor - iş için doğru aracı kullanın . İlişkisel bir veritabanını neredeyse her tür veriyi depolamaya zorlayabilir ve Mongo'yu ilişkisel verileri işlemeye zorlayabilirsiniz, ancak bunun bedeli nedir? Şema tasarımından uygulama koduna kadar tüm geliştirme ve bakım düzeylerinde karmaşıklık ortaya çıkarırsınız; performans hitinden bahsetmeye bile gerek yok.

2014 yılında, belirli veri türlerini son derece iyi işleyen birçok veritabanı sunucusuna erişimimiz var.

  • Mongo (belge saklama)
  • Redis (anahtar / değer veri depolama)
  • MySQL / Maria / PostgreSQL / Oracle / etc (ilişkisel veriler)
  • CouchDB (JSON)

Eminim RabbirMQ ve Cassandra gibi bazılarını özlemişimdir. Demek istediğim, saklamanız gereken veriler için doğru aracı kullanın.

Uygulamanız çeşitli verilerin gerçekten çok hızlı bir şekilde depolanmasını ve alınmasını gerektiriyorsa (ve kim istemez) bir uygulama için birden fazla veri kaynağı kullanmaktan çekinmez. En popüler web çerçeveleri, birden çok veri kaynağı (Rails, Django, Grails, Cake, Zend, vb.) İçin destek sağlar. Bu strateji, karmaşıklığı uygulamanın belirli bir alanı, ORM veya uygulamanın veri kaynağı arabirimi ile sınırlar.


1
Sizce RabbitMQ bir veritabanı sunucusu mu yoksa bir çeşit mi? Herhangi bir mesajı kaybetmemek için hoş bir küçük kalıcılık özelliğine sahip mesaj odaklı bir ara yazılım olduğunu söyleyebilirim, ancak verileri saklayacağım hiçbir şey yok. Sadece iki sentim.
Osiriz

@Osiriz: Haklısın. Muhtemelen bu tartışmaya dahil etmemeliydim.
CheddarMonkey

5

Burada, bir JSON dizisinin anahtarlarını bir sütuna kaydedecek / güncelleyecek bir işlev ve JSON değerlerini alan başka bir işlev bulunmaktadır. Bu işlevler, JSON dizisini depolayan sütun adının json olduğu varsayılarak oluşturulur . PDO kullanıyor .

Kaydet / Güncelle İşlevi

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

nerede $ uid kullanıcının id, $ anahtar - güncellemesine JSON anahtar ve 's değeri olarak zikredilir $ val .

Değer Alma Fonksiyonu

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

nerede $ anahtar bir anahtardır JSON biz değerine ihtiyacımız hangi dizide.


1
Bu, çelişkili durumlarda başarısız olur, ya az önce okuduğunuz json başka bir işlem tarafından güncellenirse ve ardından json'u üzerine yazarak mevcut iş parçacığına kaydederseniz? SELECT FOR UPDATEJson verileri gibi kilitlere veya sürüm oluşturmaya ihtiyacınız olabilir .
DhruvPathak

@DhruvPathak SELECT FOR UPDATEDaha iyi olması için kullanarak cevabı güncelleyebilir misiniz lütfen ? Nasıl kullanacağımı bilmiyorum.
Subin

3

MySQL'de JSON depolamak için erken destek, MySQL 5.7.7 JSON labs sürümüne ( linux ikili dosyaları , kaynak ) eklendi! Sürüm, JSON ile ilgili kullanıcı tanımlı bir dizi işlevden 2013 yılında tekrar ortaya çıkmış gibi görünüyor .

Bu yeni ortaya çıkan yerel JSON desteği, JSN_EXTRACT işlevinin her erişimi ayrıştırmak yerine ikili aramalar gerçekleştirmesine izin veren başlangıçtaki bir arama tablosu içeren optimize edilmiş bir ikili depolama biçimi olan INSERT üzerinde JSON doğrulaması da dahil olmak üzere çok olumlu bir yönde ilerliyor gibi görünüyor. Ayrıca, belirli JSON veri türlerini işlemek ve sorgulamak için bir sürü yeni işlev vardır:

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, yukarıdaki bu yeni işlevsellik için harika bir kullanım durumudur; birçok SQL veritabanının zaten bir kullanıcı tablosu vardır ve değişen bir dizi kullanıcı tercihini barındırmak için sonsuz şema değişiklikleri yapmak yerine, tek bir JSON sütununa sahip JOINolmak mükemmeldir. Özellikle tek tek öğeler için sorgulanması gerekmeyeceği için.

Henüz erken olsa da, MySQL sunucu ekip değişikliklerini iletişim büyük bir iş yaptığını üzerinde blogda .


2

JSON'u bir mysql veritabanında depolamanın, kullanılması amaçlanan RDBMS'yi kullanma amacını ortadan kaldıracağına inanıyorum. Sadece karmaşıklık katmakla kalmayıp aynı zamanda nasıl kullanıldığına bağlı olarak performansı kolayca etkileyebileceği için bir noktada manipüle edilecek veya rapor edilecek herhangi bir veride kullanmam.

Ancak, başka birinin bunu gerçekten yapmak için olası bir neden düşünüp düşünmediğini merak ettim. Günlük kaydı için bir istisna yapmayı düşünüyordum. Benim durumumda, değişken miktarda parametre ve hata içeren istekleri günlüğe kaydetmek istiyorum. Bu durumda, istek türleri için tablolar kullanmak istiyorum ve istekler, elde edilen farklı değerlerden oluşan bir JSON dizesi ile.

Yukarıdaki durumda, istekler günlüğe kaydedilir ve JSON dizesi alanında asla işlenmez veya dizine eklenmez. ANCAK, daha karmaşık bir ortamda, muhtemelen bu tür veriler için daha fazla niyeti olan bir şeyi kullanmaya ve bu sistemle depolamaya çalışacağım. Başkalarının dediği gibi, gerçekten neyi başarmaya çalıştığınıza bağlıdır, ancak standartlara uymak her zaman uzun ömür ve güvenilirliğe yardımcı olur!


2

JSON, PostgreSQL veritabanında da geçerli bir veri türüdür. Ancak, MySQL veritabanı henüz resmi olarak JSON'u desteklemiyor. Ama pişiyor: http://mysqlserverteam.com/json-labs-release-native-json-data-type-and-binary-format/

Ayrıca, bazı verilerin bir veritabanında bir dizeye serileştirilmesinin daha iyi olduğu birçok geçerli durum olduğunu kabul ediyorum. Birincil neden, düzenli olarak sorgulanmaması ve kendi şemasının değişmesi olabilir - buna karşılık gelen veritabanı şemasını değiştirmek istemezsiniz. İkinci neden, serileştirilmiş dizenin doğrudan dış kaynaklardan olması, herhangi birini kullanana kadar hepsini ayrıştırıp veri tabanında herhangi bir maliyetle beslemek istemeyebilirsiniz. Bu yüzden, farklı veritabanı arasında geçiş yapmak daha kolay olacağından, yeni MySQL sürümünün JSON'u desteklemesini bekliyor olacağım.


1

Bir proje için herhangi bir şeyi kaydetmek için json kullanıyorum, aslında üç tablo kullanıyorum! biri json'daki veriler için, biri json yapısının her meta verisinin indeksi için (her meta benzersiz bir id ile kodlanmıştır) ve biri oturum kullanıcısı için, hepsi bu. Kıyaslama, bu erken kod durumunda ölçülemez, ancak örneğin, bir kategori (veya kullanıcı olarak herhangi bir şey, ...) almak için kullanıcı görünümleri (indeksle iç birleştirme) ve çok yavaştı (çok çok yavaş , mysql'de kullanılan görünüm iyi bir yol değildir). Bu yapıdaki arama modülü istediğim her şeyi yapabilir, ancak bence bu tam json veri kaydı konseptinde mongodb daha verimli olacak. Örneğim için, kategori ağacı ve ekmek kırıntısı oluşturmak için görüşleri kullanıyorum! yapılacak çok fazla sorgu var! apache'nin kendisi gitti! ve aslında, bu küçük web sitesi için, ağaç ve kırıntı oluşturan bir php biliyorum, verilerin çıkarılması arama modülü (sadece indeks kullanan) tarafından yapılır, veri tablosu sadece güncelleme için kullanılır. İstersem, tüm dizinleri yok edebilir ve her veriyle yeniden oluşturabilirim ve tüm verileri (json) yok etmek ve yalnızca dizin tablosu ile yeniden oluşturmak gibi ters iş yapabilirim. Projem genç, php ve mysql altında çalışıyor, ancak bazen js ve mongodb düğümünü kullanmak bu proje için daha verimli olacak.

Yapabileceğinizi düşünüyorsanız json kullanın, sadece yapın, çünkü yapabilirsiniz! ve eğer bir hata ise unutun; iyi veya kötü seçim yaparak deneyin, ama deneyin!

Düşük

bir fransız kullanıcı


1
Anlamadım Anadilinde İngilizce konuşmuyorum, ancak fikirlerinizi düzenlemek için nokta (.), Virgül (,) ve paragrafları (Enter tuşu) kullanmanızı tavsiye ederim. Ardından, ancak o zaman bir veritabanı düzenlemeye çalışın ;-)
Diego Jancic

Haklısın, kafa karıştırıcı cevap aslında örnek göstererek daha açık olmalı. Ancak, mysql mongoDB ile değiştirilebiliyorsa, mysql zorunlu ise json (mongodb için yerel olarak) kullanmak daha verimli olacaktır, tamam, birkaç gün sonra tekrar deneyelim!
düşük

1

Bunun gerçekten geç olduğunu biliyorum, ancak tabloları bir noktaya kadar normalleştirme RDBMS standartlarını sürdürmek ve ardından verileri bu noktanın ötesinde JSON'da metin değeri olarak depolamak için hibrit bir yaklaşım kullandığım benzer bir durum yaşadım. Örneğin RDBMS normalleştirme kurallarını izleyerek verileri 4 tabloda depoluyorum. Ancak dinamik şemaya uyum sağlamak için 4. tabloda verileri JSON formatında depoluyorum. Her veri almak istediğimde JSON verilerini alıyorum, ayrıştırıyorum ve Java'da görüntülüyorum. Bu şimdiye kadar benim için çalıştı ve tablodaki json verilerine dönüştürdüğüm alanları bir ETL kullanarak normalleştirilmiş bir şekilde hala indeksleyebildiğimden emin olmak için. Bu, kullanıcının uygulama üzerinde çalışırken minimum gecikmeyle karşılaşmasını ve alanların veri analizi vb. İçin RDBMS dostu bir biçime dönüştürülmesini sağlar.


0

Bu özü kullanabilirsiniz: https://gist.github.com/AminaG/33d90cb99c26298c48f670b8ffac39c3

Sunucuya yükledikten sonra (süper değil, sadece kök ayrıcalığına ihtiyacınız var), aşağıdaki gibi bir şey yapabilirsiniz:

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

Geri dönecek a 2 kullanarak JSON içindeki herhangi bir şeyi döndürebilirsiniz İyi yanı, MySQL 5.1,5.2,5.6'yı desteklemesidir. Ve sunucuya herhangi bir ikili program kurmanıza gerek yoktur.

Eski projeye dayalı common-schema, ancak bugün hala çalışıyor https://code.google.com/archive/p/common-schema/


öz
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.