Posting meta vs tabel database terpisah


29

Saat mengembangkan plugin yang memerlukan penyimpanan data, apa pro dan kontra dari menggunakan satu metode atau lainnya?

The penjelasan yang diberikan di naskah kuno itu tidak rinci:

Namun, sebelum melompat dengan seluruh tabel baru, pertimbangkan apakah menyimpan data plugin Anda di Post Meta WordPress (alias Bidang Kustom) akan bekerja. Post Meta adalah metode yang disukai; gunakan jika memungkinkan / praktis.


FYI: MB Custom Table adalah plugin yang dapat menyimpan data meta ke tabel khusus alih-alih tabel meta posting WP.
Anh Tran

Jawaban:


30

Nah, jika saya mengambil topi kiddie script WP, jawaban saya adalah: gunakan post_meta, selalu.

Namun, saya kebetulan tahu satu atau dua hal tentang database, jadi jawaban saya adalah: tidak pernah, pernah, menggunakan EAV (alias tabel post_meta) untuk menyimpan data yang mungkin perlu Anda kueri.

Di depan indeks, pada dasarnya tidak ada yang layak digunakan dalam tabel meta. Jadi, jika Anda menyimpan tipe data XYZ dan berharap Anda menanyakan semua posting yang memiliki XYZ dengan nilai 'abc', well ... semoga sukses. (Lihat semua tiket terkait pengguna / peran / topi di WP trac untuk memberi Anda gambaran tentang bagaimana darah itu bisa didapat.)

Di bagian gabungan, Anda dengan cepat menabrak batas di mana pengoptimal memutuskan untuk menggunakan algoritma generik alih-alih menganalisis kueri saat ada beberapa kriteria gabungan.

Jadi, tidak, tidak, tidak, tidak. Jangan pernah, pernah, pernah menggunakan meta. Kecuali jika yang Anda simpan adalah kosmetik dan tidak akan pernah menjadi bagian dari kriteria kueri.

Itu rusak ke aplikasi Anda. Jika Anda menyimpan, katakanlah, tanggal lahir seorang sutradara film, daripada masalah besar. Gunakan meta yang Anda inginkan. Tetapi jika Anda menyimpan, misalnya, tanggal rilis film, Anda akan gila untuk tidak menggunakan tabel terpisah (atau menambahkan kolom ke tabel posting) dan menambahkan indeks ke kolom itu.


1
Ya, plugin yang saya kembangkan menangani data khusus seperti acara, berita, siaran pers, tawaran kerja ... Dari luar "WordPress World", menggunakan tabel bukanlah pilihan. Tetapi saran dari WordPress Codex, agak membingungkan. Bagaimana potongan-potongan data serial dapat lebih disukai daripada data yang dinormalisasi / terstruktur / terindeks?
Nassif Bourguig

1
Jika Anda bertanya rata-rata WP dev, ia kemungkinan akan menjawab "gunakan meta" atau "gunakan taksonomi". Dan saya setuju, sampai pada titik di mana Anda perlu menanyakannya. Jika demikian, dan saya yakin ini adalah kasus Anda, satu-satunya jawaban saya adalah, tambahkan bidang ke tabel posting, atau buat tabel terpisah seluruhnya. Jika tidak, Anda akan menghadapi masalah kinerja yang luar biasa dalam soal kueri dan, yang lebih penting lagi untuk daftar node, pengurutan top-n.
Denis de Bernardy

1
Denis apakah Anda dapat menguraikan ini sedikit lebih, saya merasa sangat informatif tetapi akan menyukai beberapa data lagi, adakah yang melakukan tes ?, apa sebenarnya kelemahan dan keterbatasan utama, terima kasih.
Wyck

6
@Denis - Advokasi penuh gairah terhadap postmeta, eh? Anda tahu bahwa Anda menentang keras ortodoksi dan Anda akan jatuh dari rahmat baik para imam besar gereja puisi kode jika Anda bertahan dalam pembicaraan seperti itu, bukan? :-) Tapi serius bukankah Anda pikir Anda melebih-lebihkan sedikit? Itu benar-benar tergantung pada apakah akan ada puluhan ribu catatan meta atau tidak. Dalam banyak kasus tidak cukup catatan yang perlu dikhawatirkan. Satu situs kompleks yang saya gunakan memiliki sekitar 10.000 catatan meta dengan beberapa catatan baru yang direncanakan, dan tidak apa-apa (fyi, ini bukan blog.)
MikeSchinkel

1
@Denis - Terima kasih atas komentarnya. Dan jangan salah paham, saya mungkin lebih condong ke perspektif Anda tetapi kombinasi dari 1.) perdebatan selama satu jam dengan Matt di WordCamp Birmingham tentang manfaat bidang mirip Pods dan 2.) kesederhanaan meta telah mengundurkan diri untuk memusatkan perhatian saya pada masalah lain yang berpotensi saya ubah. Di WCB saya datang menyadari selama Matt bertanggung jawab, itu tidak akan berubah karena (tebakan saya) Matt begitu terpikat dengan gagasan tabel yang lebih sedikit sehingga dia tidak akan membiarkan dirinya mengenali sisi bawah pengindeksan pada 768 byte kunci. <sigh>
MikeSchinkel

5

Jika plugin Anda akan memiliki BANYAK data, maka menggunakan wp_postmetaBUKAN ide yang baik seperti yang ditunjukkan di bawah ini:

Mengambil WooCommerce sebagai contoh, di toko dengan ~ 30.000 produk, akan ada rata-rata, ~ 40 pos meta (atribut dan semuanya) per produk, 5 gambar produk per produk, yang berarti akan ada ~ 4 gambar meta untuk setiap gambar:

30.000 produk x 40 meta masing-masing = 1.200.000 baris di wp_postmeta

+

30.000 produk x 5 gambar setiap x 4 meta gambar untuk masing-masing = 600.000 baris di wp_postmeta

Jadi hanya dengan 30.000 produk yang Anda cari memiliki 1.800.000 baris wp_postmeta.

Jika Anda menambahkan lebih banyak properti ke produk Anda atau gambar produk Anda, nomor ini akan berlipat ganda.

Masalahnya ada dua:

  • Bergabung sendiri sangat mahal dengan MySQL
  • wp_postmetatabel tidak diindeks kecuali Anda menggunakan versi mysql nanti (yaitu tidak ada indeks FULLTEXT untuk meta_value)

Untuk memberikan contoh dari kasus aktual:

SELECT meta_value FROM wp_postmeta WHERE meta_key LIKE '_shipping_city'

Ini memilih kota pengiriman dari semua detail pesanan dengan kekalahan ~ 3 detik pada server khusus level entri bahkan jika ada 5-10 pesanan . Ini karena kueri dijalankan dari wp_postmetatabel yang memiliki ~ 3 juta baris dalam instalasi langsung.

Bahkan beranda datang cukup lambat, karena tema menarik berbagai elemen dari wp_postmeta- slider, beberapa sisipan ulasan, beberapa meta lainnya. Secara umum daftar produk sangat lambat, pencarian juga lambat ketika mendaftarkan produk.

Anda tidak dapat memperbaikinya melalui cara normal apa pun. Anda dapat menempatkan Pencarian Elastis di server Anda dan menggunakan plugin Pencarian Elastis di Wordpress, Anda dapat menggunakan redis / memcached, Anda dapat menggunakan plugin cache halaman yang baik, tetapi pada akhirnya masalah mendasar akan tetap - mengambil sejumlah data dari kembung wp_postmetatabel akan lambat, setiap kali dilakukan. Di server tempat saya menguji solusi yang saya terapkan di bawah ini, semua ini diinstal dan dikonfigurasikan dengan benar dan dioptimalkan, dan situs bekerja dengan baik-baik saja untuk pengguna yang tidak masuk atau pertanyaan yang biasa dilakukan sejak plugin caching dimulai.

Tetapi saat pengguna yang masuk mencoba melakukan sesuatu yang tidak biasa dilakukan atau crons, caching plugins, atau utilitas lain ingin mengambil data aktual dari db untuk menyimpannya atau melakukan hal lain, semuanya berjalan lambat.

Jadi saya mencoba sesuatu yang lain:

Saya memberi kode plugin kecil untuk mengambil semua meta produk (postmeta untuk produk tipe posting ) ke tabel kustom yang dihasilkan oleh kode. Plugin ini mengambil semua meta untuk setiap posting dan membuat tabel dengan menambahkan setiap meta sebagai kolom dan memasukkan nilai ke dalam setiap baris. Saya mengubah format EAV menjadi format relasional mendatar dan datar. Saya juga punya plugin untuk menghapus postmeta dari semua produk yang dipindahkan dari wp_postmetatabel.

Sementara saya melakukannya, saya memindahkan postmeta lampiran dan semua meta tipe posting lainnya ke tabel mereka sendiri.

Lalu saya terhubung ke get_(post_type)_metafilter untuk mengganti pengambilan metadata untuk melayani mereka dari tabel kustom baru.

Sekarang permintaan yang sama dari sebelumnya, yang mengambil ~ 3 detik untuk mengambil dari wp_postmetamengambil ~ 0,006 detik. Situs sekarang berperilaku seolah-olah itu adalah instalasi WP baru.

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

Tentu, melakukan hal-hal dengan cara Wordpress lebih baik. Ini sebenarnya norma.

Namun , juga pengetahuan yang jelas bahwa tabel EAV sangat tidak efisien dalam penskalaan. Ini sangat fleksibel dan memungkinkan Anda menyimpan data apa pun, tetapi harga yang Anda bayar untuk itu, adalah kinerja. Ini merupakan trade off yang mendasar.

Dalam konteks itu, sulit untuk memberitahu seseorang yang berniat untuk memiliki banyak data dan - tuhan melarang - permintaan / pencarian data itu untuk menggunakan wp_postmetatabel pasti. Performa hit akan sangat bagus.

Menggunakan tabel khusus Anda akan memungkinkan data Anda menumpuk dan masih cukup cepat.

Seperti halnya Pippin Williams, pembuat plugin Easy Digital Downloads menyebutkan bahwa dia akan menggunakan tabel khusus jika dia baru memulai pengkodean pluginnya, jika Anda akan membuat sesuatu yang akan digunakan untuk waktu yang lama atau menumpuk banyak data, lebih efisien menggunakan tabel khusus jika Anda mendesainnya dengan baik.

Anda harus memastikan bahwa pengembang plugin / addon lain memiliki cara untuk menghubungkan ke plugin Anda untuk memanipulasi data Anda sebelum dan sesudah pengambilan data. Jika Anda melakukannya, maka Anda cukup solid.


1
Hal menarik! Satu hal yang perlu diklarifikasi adalah bahwa filter "get_ (post_type) _meta" tersebut sebenarnya disebut "get_ (meta-type) _metadata", di mana meta-type adalah posting, komentar atau pengguna. Jadi get_post_meta () akan melalui filter get_post_metadata, terlepas dari jenis posting. Nilai pengembalian filter adalah apa yang Anda inginkan menjadi nilai meta akhir.
Berend

get_ (meta-type) _metadata -> memang berfungsi dengan semua tipe posting, dan memang fungsi terakhir yang dikunjungi adalah get_post_metadata. Namun filter berfungsi saat Anda menggunakannya.
unity100

2

Itu tergantung pada apa yang Anda lakukan. Cara WP adalah dengan menggunakan tabel yang ada, karena mereka telah dirancang agar cukup fleksibel, namun kadang-kadang Anda akan mencapai kelas data baru yang tidak dapat ditempatkan di tabel yang sudah ada, misalnya jika Anda menginginkan meta data kategori , Anda dapat memilih untuk membuat tabel wp_termsmeta.

Namun, biasanya Anda dapat menyimpan data dengan cukup nyaman di berbagai tabel yang ada, dan tempat Anda menyimpan data tergantung pada apa yang dilakukan plugin Anda.

  • Untuk pengaturan plugin umum, gunakan panggilan get_option () API - ini juga akan di-cache.
  • Untuk pengaturan plugin yang khusus untuk setiap posting, kemudian gunakan data meta khusus per posting dengan get_post_meta () . Ini biasanya banyak untuk apa yang Anda butuhkan.

Caching diterapkan dalam WordPress untuk mempercepat waktu respons Anda juga.


1

setuju dengan denis 100%. Tapi ada jalan lain.

Masalah dengan menggunakan meta posting untuk nilai yang akan ditanyakan adalah ketika nilainya array dll. Seperti ini:

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

Ini akan disimpan dalam db sebagai string serial, yang akan terlihat seperti ini:

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

Jadi ketika Anda ingin menanyakan semua posting dengan array['key2'] = 'val 2'wp maka harus menarik setiap entri meta yang disebut array, membongkar, lalu mengujinya, lalu pergi ke yang berikutnya. Ini pasti akan menurunkan server Anda jika situs Anda berhasil dan memiliki banyak posting, halaman, posting kustom dll.

Solusinya tergantung pada proyek, dan Anda akan tahu sebabnya. Jika Anda menyimpan data sebagai var = valwp maka akan dapat mencari tanpa memiliki php untuk membongkar setiap tes. Untuk melakukan ini dalam skenario di atas Anda akan menggunakan beberapa namespacing dan menyimpan kunci meta:

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

kemudian wp mencari kunci 2 dengan val 2 akan dapat menariknya langsung. Ini tergantung proyek. Proyek saya saat ini bergantung pada sekitar 20 tipe data yang berbeda untuk disimpan dengan setiap posting kustom sehingga di atas hanya akan membuat tabel besar untuk mencari, melihat bagaimana kita mengharapkan 100 dari ribuan posting. Jadi dalam skenario itu tabel kustom adalah satu-satunya cara.

Semoga ini bisa membantu seseorang


0

Untuk situs FarmVille saya :) Saya melakukan keduanya tetapi tidak pernah menyelesaikannya karena saya menjualnya:

  1. Saya membaca farmville xml dan membuang data dalam tabel khusus
  2. Di WordPress saya memiliki bidang khusus yang dibuat secara otomatis untuk setiap bidang dalam tabel itu (dan beberapa tambahan)
  3. Sekarang khawatir tentang apa yang terjadi jika nilai berubah di tabel atau di sisi lain: bidang khusus karena mereka harus terus disinkronkan

Saya melakukan ini karena saya ingin di satu sisi memiliki pengguna mengedit situs wordpress dengan memasukkan data farmville baru misalnya "sapi biaya 10 koin" TETAPI dari sisi integrasi: JIKA perubahan dalam xml dan sapi sekarang harganya "20 koin" (melalui plugin pengeditan front-end) yang akan diberikan sebagai opsi setelahnya: agar XML ATAU pengguna benar (semacam sistem wiki).

Jadi di sini adalah contoh saat menggunakan keduanya.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.