Meta ve ayrı veritabanı tablolarını yayınla


29

Veri depolama gerektiren eklentiler geliştirirken, bir yöntem ya da diğerini kullanmanın avantajları ve dezavantajları nelerdir?

Kodeksine verilen açıklama ayrıntılı değildir:

Ancak, tamamen yeni bir tabloya girmeden önce, eklentinizin verilerini WordPress 'Post Meta'da (aka Özel Alanlar) saklamanın işe yarayıp yaramayacağını düşünün. Meta sonrası tercih edilen yöntemdir; Mümkün / pratik olduğunda kullanın.


Bilginize: MB Özel Tablo meta verileri WP'nin post meta tablosu yerine özel tablolara kaydedebilen bir eklentidir.
Anh Tran

Yanıtlar:


30

Eğer bir WP senaryosunun çocuğunun şapkasını alırsam, cevabım şöyle olur: her zaman, post_meta kullanın.

Ancak, veritabanları hakkında bir veya iki şey biliyorum, bu yüzden cevabım: asla, asla, asla, sorgulamanız gerekebilecek verileri depolamak için bir EAV (aka post_meta tablosu) kullanmayın.

İndeks cephesinde meta tablolarda kullanılmaya değmez. Bu nedenle, XYZ veri türünü saklıyorsanız ve XYZ olan tüm gönderileri sorgulamanızı umuyorsa 'abc', iyi şanslar. (WP trac'teki tüm kullanıcılara / rollere / keplere ilişkin biletleri görün ve size ne kadar sinirlenebileceği hakkında bir fikir verin.)

Birleştirme cephesinde, optimize edicinin, birden çok birleştirme ölçütü olduğunda sorguyu analiz etmek yerine genel bir algoritma kullanmaya karar verdiği sınırla hızla çarpışırsınız.

Böylece, hayır, hayır, hayır, hayır. Asla, asla, asla meta kullanma. Sakladığınız şey kozmetik olmadıkça ve hiçbir zaman bir sorgu kriterinin parçası olmayacak.

Uygulamanıza ayrılıyor. Saklamak istiyorsan, bir film yönetmeninin doğum tarihini hatırlatmak çok önemli. İstediğin kadar meta kullan. Ancak, bir filmin çıkış tarihini saklıyorsanız, ayrı bir tablo kullanmamayı (veya yazılar tablosuna sütun eklemeyi) ve söz konusu sütuna bir dizin eklemeyi tercih edersiniz.


1
Evet, geliştirdiğim eklentiler; olaylar, haberler, basın bültenleri, İş teklifleri gibi özel verileri işliyor. "WordPress World" dışından, tabloları kullanmak gerçekten bir seçenek değil. Ancak WordPress Kodeksi'nden gelen tavsiyeler biraz kafa karıştırıcıdır. Serileştirilmiş veri parçaları normalize edilmiş / yapılandırılmış / dizine alınmış verilerde nasıl tercih edilebilir?
Nassif Bourguig,

1
Ortalama WP dev'e sorarsanız, muhtemelen "bir meta kullanın" veya "bir taksonomi kullanın" diye cevap verecektir. Ve buna karşı sorgulamanız gereken noktaya kadar katılıyorum. Öyleyse, sizin durumunuz olduğuna inanıyorum, tek cevabım, alanları yazı tablosuna eklemek veya tamamen ayrı bir tablo oluşturmak. Sorgulama ve daha da önemlisi düğüm listeleri için en üst düzey sıralama söz konusu olduğunda, muazzam performans sorunları için bulunmazsınız.
Denis de Bernardy

1
Denis bunu biraz daha açıklayabilir, onu çok bilgilendirici buluyorum, ancak biraz daha fazla veriye katılır, testleri yapan var mı ?, tam olarak en büyük dezavantajları ve kısıtlamaları nelerdir, teşekkürler.
Wyck,

6
@Denis - Postmeta'ya karşı tutkulu bir savunuculuk, ha? Ortodoksluğa sıkıca gittiğinizi biliyorsunuz ve böyle bir konuşmaya devam ederseniz yüksek kod şiir kilisesi papazlarının iyiliğinden mahrum kalacaksınız, değil mi? :-) Ama cidden biraz fazla abarttığını düşünmüyor musun? Gerçekten de on binlerce meta kayıt olup olmayacağına bağlı. Çoğu durumda endişelenecek yeterli kayıt yoktur.
Dağıtmakta

1
@Denis - Yorumlarınız için teşekkür ederiz. Ve beni yanlış anlama, muhtemelen bakış açınıza daha çok eğilirim ama 1) WordCamp Birmingham'da Matt ile Pod'lara benzer alanların özellikleri üzerinde bir saatlik bir tartışma ve 2.) meta basitliği dikkatimi potansiyel olarak değiştirebileceğim diğer konulara odaklamak için istifa etti. WCB'de Matt'in sorumlu olduğu sürece farkına varmadım çünkü değişmeyecek çünkü (sanırım) Matt, 768 baytta indekslemenin aşağı taraflarını tanımasına izin vermeyeceği, daha az tablo fikriyle çok şaşırdı. tuşuna basın. <sigh>
MikeSchinkel

5

Eklentiniz çok fazla veriye sahip olacaksa, kullanımı wp_postmetaaşağıda gösterildiği gibi iyi bir fikir DEĞİLDİR:

WooCommerce'i örnek alarak, ~ 30.000 ürüne sahip bir mağazada, ürün başına ortalama ~ 40 post meta (nitelik ve her şey), ürün başına 5 ürün resmi olacak, yani ürün başına 4 ürün meta olacak Her görüntü için:

30.000 ürün x 40 meta = 1.200.000 satır wp_postmeta

+

30.000 ürün x 5 görüntü, her biri için = x 600.000 satır için x x görüntü wp_postmeta

Yani sadece 30.000 ürünle 1.800.000 satırın olmasını bekliyorsunuz wp_postmeta.

Ürünlerinize veya ürün resimlerinize daha fazla özellik eklerseniz, bu sayı çarpılacaktır.

Bununla ilgili sorun iki yönlüdür:

  • MySQL ile öz katılım çok pahalı
  • wp_postmetaDaha sonra mysql sürümleri kullanmıyorsanız tablo indekslenmez (yani FULLTEXT indeksi yoktur meta_value)

Gerçek bir davadan bir örnek vermek için:

SELECT meta_value FROM wp_postmeta WHERE meta_key LIKE '_shipping_city'

Bu, tüm sipariş ayrıntılarından nakliye şehrini seçer ve giriş seviyesi tahsis edilmiş bir sunucuda 5-10 sipariş olsa bile yaklaşık 3 saniye gelir . Bunun nedeni, sorgunun wp_postmetacanlı kurulumda ~ 3 milyon satır içeren bir tablodan çalıştırılmasıdır .

Ana sayfa bile yavaş geliyor, çünkü tema çeşitli öğeleri wp_postmeta- kaydırıcılardan, birkaç inceleme ekinden, birkaç başka metadan alıyor. Genel olarak ürün listeleme işlemi çok yavaştır, ürün listeleme işlemi sırasında aramalar benzer şekilde yavaştır.

Bunu normal yöntemlerle düzeltemezsiniz. Elastik Arama'yı sunucunuza yerleştirebilir ve Wordpress'te bir Elastik Arama eklentisi kullanabilirsiniz, redis / memcached kullanabilirsiniz, iyi bir sayfa önbellek eklentisi kullanabilirsiniz, ancak sonuçta temel sorun devam edecektir - şişirilmiş herhangi bir miktarda veri almak wp_postmetaNe zaman yapılırsa masa yavaşlar. Aşağıda uygulamaya koyduğum çözümü test ettiğim sunucuda, tüm bunlar düzgün bir şekilde kurulmuş ve yapılandırılmış ve optimize edilmiş ve site, giriş yapmayan kullanıcılar veya önbelleğe alınan eklentilerin başlatılmasından bu yana sıkça yapılan sorgular için tamamen uygun şekilde çalıştı.

Ancak, oturum açan bir kullanıcının sık yapılan bir şey yapmayı denediği andan beri, kasetler, eklentileri önbelleğe almak veya herhangi bir yardımcı program, önbelleğe almak veya başka bir şey yapmak için db'den gerçek verileri almak istedi, işler yavaşladı.

Bu yüzden başka bir şey denedim:

Tüm ürün metalarını (post tip ürün için postmeta ) kod tarafından oluşturulan özel bir tabloya almak için küçük bir eklenti kodladım . Bu eklenti her gönderi için tüm metaları aldı ve her metayı sütun olarak ekleyerek ve değerleri her satıra ekleyerek bir tablo oluşturdu. EAV formatını yatay, düz bir ilişkisel formata dönüştürdüm. Ayrıca postmeta'yı wp_postmetatablodan taşınan tüm ürünlerden silmek için de eklentim vardı .

Ben onun yanındayken, ek posta metalarını ve diğer tüm yazı tiplerinin metalarını kendi tablolarına taşıdım .

Daha sonra get_(post_type)_meta, yeni özel tablolardan sunulmak üzere meta verilerin alınmasını geçersiz kılmak için filtreye bağladım .

Şimdi aynı sorguyu daha önce sordum, bu sayı ~ 3 saniye sürdü wp_postmeta, ~ 0,006 saniye alıyor. Site şimdi yeni bir WP kurulumuymuş gibi davranıyor.

....................

Doğal olarak, işleri Wordpress yoluyla yapmak daha iyidir. Aslında bu norm.

Bununla birlikte , EAV tablosunun ölçeklendirmede çok verimsiz olduğu da açıktır. Sonsuzca esnektir ve herhangi bir veri depolamanıza izin verir, ancak bunun için ödediğiniz fiyat performanstır. Bu temel bir işlemdir.

Bu bağlamda, bir yığın ton veriye sahip olmak isteyen birisine ve - tanrıyı yasakla - bu veriyi sorgulamak / araştırmak, wp_postmetatablonun kesin olarak kullanması zor . Performans hit harika olacak.

Özel tablolarınızı kullanmak, verilerinizin toplanmasına ve hala yeterince hızlı kalmasına olanak sağlar.

Tıpkı Easy Digital Downloads eklentisinin yaratıcısı Pippin Williams'ın, eklentisini kodlamaya yeni başlıyorsa, uzun süre kullanacak veya çok fazla veri toplayacak bir şey oluşturacaksanız, özel tablolar kullanacağından bahsettiği gibi, Özel masalarınızı iyi tasarlarsanız kullanmak daha verimlidir.

Başka herhangi bir eklenti / eklenti geliştiricisinin, verilerinizi almadan önce ve sonra verilerinizi değiştirmek için eklentinize bağlanma yoluna sahip olduğundan emin olmalısınız. Bunu yaparsan, oldukça sağlamsın.


1
İlginç şeyler! Açıklığa kavuşturulması gereken bir şey, belirtilen "get_ (post_type) _meta" filtresinin aslında "get_ (meta-type) _metadata" olarak adlandırılmasıdır; burada meta-tip, yazı, yorum veya kullanıcıdır. Bu nedenle, get_post_meta (), yazı türünden bağımsız olarak get_post_metadata filtresinden geçer. Filtrenin dönüş değeri, nihai meta değerinin olmasını istediğiniz şeydir.
Berend,

get_ (meta-type) _metadata -> gerçekten tüm post tipleriyle çalışır ve gerçekten ziyaret edilen son fonksiyon get_post_metadata'dır. Ancak yine de kullandığınızda filtre çalışır.
birlik 100

2

Bu ne yaptığınıza bağlı. WP yöntemi, yeterince esnek olacak şekilde tasarlandıkları için mevcut tabloları kullanmaktır, ancak bazen varolan bir tabloya yerleştirilemeyen yeni bir veri sınıfına erişirsiniz, örneğin, kategori meta verilerini istiyorsanız , bir wp_termsmeta tablosu oluşturmayı seçebilirsiniz.

Ancak, genellikle verilerinizi varolan farklı tablolarda oldukça rahat bir şekilde saklayabilirsiniz ve verilerinizi nerede sakladığınız, eklentinizin ne yaptığına bağlıdır.

  • Genel eklenti ayarları için get_option () API çağrısını kullanın - bu önbelleğe alınacaktır.
  • Belirli bir gönderi için belirli olan eklenti ayarları için, daha sonra her yazı için get_post_meta () özel meta verilerini kullanın . Bu genellikle ihtiyacınız olan şey için çok fazla.

Önbelleğe alma, yanıt sürenizi de hızlandırmak için WordPress içinde uygulanır.


1

% 100 denis ile anlaştı. Ancak bunun bir yolu var.

Post meta'nın sorgulanacak değerler için kullanılmasındaki sorun, değerlerin dizinin vs. olduğu zamandır. Bunun gibi:

array(
'key1' => 'val 1',
'key2' => 'val 2'
);

Bu, db'de şöyle bir görünecek şekilde seri hale getirilmiş bir dizge olarak depolanır:

{array["key1"]...{}...}

Bu nedenle, tüm gönderileri sorgulamak istediğinizde array['key2'] = 'val 2'wp, array adlı her meta girişini çekmek zorundadır, paketi açın, sonra sınayın, sonra bir sonrakine geçin. Siteniz başarılıysa ve çok sayıda gönderi, sayfa, özel gönderi vb. Varsa, bu sunucunuzu kesinlikle indirecektir.

Çözüm projeye bağlı ve nedenini göreceksiniz. Verileri bir şekilde var = valsaklarsanız, wp, her bir testi açmak için php'siz arama yapabilir. Bunu yukarıdaki senaryoda yapmak için bazı isim alanlarını kullanır ve meta anahtarlarını saklarsınız:

_array_key1 = 'val 1';
_array_key2 = 'val 2';

o zaman val 2 ile anahtar 2'yi aramak wp onu hemen çekebilecek. Bu olsa projeye bağlı. Mevcut projem, her bir özel gönderiyle birlikte depolanacak yaklaşık 20 farklı veri tipine dayanmaktadır; bu nedenle yukarıdakiler, binlerce yazı göndermeyi nasıl beklediğimizi görerek, arama yapmak için büyük bir tablo oluşturur. Yani bu senaryoda, özel bir tablo tek yoldur.

Umarım bu birine yardımcı olur


0

FarmVille sitem için :) Her ikisini de yaptım ama satmadım çünkü asla satmadım:

  1. Farmville xml dosyasını okudum ve verileri özel bir tabloda topladım
  2. WordPress'te o tablodaki her alan için otomatik olarak özel alanlar hazırladım (ve bazı ekstralar)
  3. Şimdi bir tabloda veya diğer tarafta bir değer değişirse ne olacağından endişe edin: sürekli senkronize olması gerektiğinden özel alan

Bunu yaptım çünkü bir yandan kullanıcıların yeni farmville verilerini girerek WordPress sitesini düzenlemelerini istedim, örneğin "bir ineğin fiyatı 10 jeton" ANCAK entegrasyon tarafından: Eğer xml'deki bir değişiklik eğer ineğin fiyatı "20 jeton" ise (ön uç düzenleme eklentisi aracılığıyla) ondan sonra seçenek olarak verilecek: böylece XML VEYA kullanıcı haklıydı (wiki sisteminin bir türü).

Yani burada her ikisini de kullanırken bir örnek.

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.