โพสต์ meta vs ตารางฐานข้อมูลแยกต่างหาก


29

เมื่อพัฒนาปลั๊กอินที่ต้องใช้ที่เก็บข้อมูลข้อดีและข้อเสียของการใช้วิธีการหนึ่งหรืออย่างอื่นคืออะไร

คำอธิบายที่ได้รับใน Codexไม่ได้รายละเอียด:

อย่างไรก็ตามก่อนที่จะกระโดดเข้ามาพร้อมกับตารางใหม่ทั้งหมดให้พิจารณาว่าการจัดเก็บข้อมูลปลั๊กอินของคุณใน WordPress 'Post Meta (หรือฟิลด์ที่กำหนดเอง) จะทำงานได้หรือไม่ Post Meta เป็นวิธีการที่ต้องการ ใช้เมื่อเป็นไปได้ / ในทางปฏิบัติ


FYI: MB Custom Tableเป็นปลั๊กอินที่สามารถเก็บข้อมูล meta ไปยังตารางที่กำหนดเองแทนตาราง post meta ของ WP
Anh Tran

คำตอบ:


30

ถ้าฉันใส่หมวกของ WP สคริปต์ตัวเล็กคำตอบของฉันจะเป็น: ใช้ post_meta เสมอ

อย่างไรก็ตามฉันรู้สิ่งหนึ่งหรือสองเกี่ยวกับฐานข้อมูลดังนั้นคำตอบของฉันคือ: ไม่เคยเคยใช้ EAV (หรือตาราง post_meta) เพื่อจัดเก็บข้อมูลที่คุณอาจต้องการสอบถาม

ที่ด้านหน้าดัชนีไม่มีค่าที่ใช้ในเมตาตาราง ดังนั้นหากคุณกำลังจัดเก็บประเภทข้อมูล XYZ และหวังว่าคุณจะค้นหาโพสต์ทั้งหมดที่มี XYZ ด้วยมูลค่าขอ'abc'ให้โชคดี ... (ดูตั๋วทั้งหมดที่เกี่ยวข้องกับผู้ใช้ / บทบาท / แคปใน WP trac เพื่อให้คุณทราบว่าจะรับเลือดได้อย่างไร)

ที่ด้านหน้าการรวมคุณจะชนกับขีด จำกัด ที่เครื่องมือเพิ่มประสิทธิภาพตัดสินใจใช้อัลกอริธึมทั่วไปแทนการวิเคราะห์คิวรีเมื่อมีเกณฑ์การเข้าร่วมหลายเกณฑ์

ดังนั้นไม่, ไม่, ไม่, ไม่ ไม่เคยเคยเคยใช้เมตา นอกจากสิ่งที่คุณเก็บไว้เป็นเครื่องสำอางและจะไม่เป็นส่วนหนึ่งของเกณฑ์การสืบค้น

แอพของคุณพังลงมา หากคุณกำลังเก็บไว้พูดวันเกิดของผู้กำกับภาพยนตร์มากกว่าเรื่องใหญ่ ใช้เมตาทั้งหมดที่คุณต้องการ แต่ถ้าคุณกำลังจัดเก็บพูดวันที่วางจำหน่ายของภาพยนตร์คุณจะต้องไม่ใช้ตารางแยกต่างหาก (หรือเพิ่มคอลัมน์ในตารางโพสต์) และเพิ่มดัชนีในคอลัมน์นั้น


1
ใช่ปลั๊กอินที่ฉันกำลังพัฒนากำลังจัดการข้อมูลที่กำหนดเองเช่นเหตุการณ์ข่าวประชาสัมพันธ์งานเสนอ ... จากนอก "WordPress World" การใช้ตารางไม่ใช่ตัวเลือกจริงๆ แต่คำแนะนำจาก WordPress Codex นั้นค่อนข้างสับสนเล็กน้อย ข้อมูลที่จัดลำดับแล้วจะเป็นที่ต้องการได้อย่างไรกับข้อมูลปกติ / โครงสร้าง / ข้อมูลที่จัดทำดัชนี?
Nassif Bourguig

1
ถ้าคุณถาม WP dev โดยเฉลี่ยเขาน่าจะตอบว่า "ใช้เมตา" หรือ "ใช้อนุกรมวิธาน" และฉันเห็นด้วยจนถึงจุดที่คุณต้องการสอบถามกับมัน ถ้าเป็นเช่นนั้นและฉันเชื่อว่าเป็นกรณีของคุณคำตอบเดียวของฉันคือเพิ่มเขตข้อมูลลงในตารางโพสต์หรือสร้างตารางแยกต่างหากทั้งหมด มิฉะนั้นคุณจะต้องเจอกับปัญหาเรื่องประสิทธิภาพที่ยิ่งใหญ่เมื่อต้องค้นหาและที่สำคัญยิ่งกว่าสำหรับรายการโหนดการเรียงลำดับบนสุด
เดนิสเดอเบอร์นาดี

1
เดนิสคุณจะสามารถอธิบายเพิ่มเติมเกี่ยวกับเรื่องนี้ได้อีกเล็กน้อยฉันพบว่ามีข้อมูลมาก แต่จะรักข้อมูลเพิ่มเติมมีใครทำข้อสอบบ้างหรือไม่ข้อเสียและข้อ จำกัด ที่สำคัญคืออะไร
Wyck

6
@Denis - ค่อนข้างสนับสนุนการต่อต้าน postmeta ใช่มั้ย คุณรู้ว่าคุณกำลังต่อต้านนิกายออร์โธดอกซ์อย่างแน่นหนาและคุณจะหลุดพ้นจากบทกวีของนักบวชชั้นสูงหากคุณยังคงพูดเช่นนั้นใช่ไหม? :-) แต่อย่างจริงจังคุณไม่คิดว่าคุณคุยโวเกินจริงหรือ มันขึ้นอยู่กับว่าจะมีการบันทึกเมตาเป็นหมื่นหรือไม่ ในหลายกรณีมีเพียงบันทึกไม่เพียงพอที่จะต้องกังวล เว็บไซต์ที่ซับซ้อนหนึ่งแห่งที่ฉันกำลังปรับใช้มีเร็กคอร์ด meta ประมาณ 10,000 รายการโดยมีการวางแผนใหม่จำนวนน้อยและมันก็ดี (fyi ไม่ใช่บล็อก)
MikeSchinkel

1
@ Denis - ขอบคุณสำหรับความคิดเห็น และอย่าเข้าใจฉันผิดฉันอาจเอนตัวเข้าหามุมมองของคุณมากขึ้น แต่เป็นการรวมกันของ 1. ) การถกเถียงกับ Matt ที่ WordCamp Birmingham ในชั่วโมงที่ยาวนานเหนือข้อดีของเขตข้อมูลที่เหมือน Pods และ 2) ความเรียบง่ายของ meta ลาออกเพื่อมุ่งเน้นความสนใจไปที่ปัญหาอื่น ๆ ที่ฉันอาจเปลี่ยนแปลงได้ ที่ WCB ฉันออกไปตระหนักว่าตราบใดที่ Matt รับผิดชอบมันจะไม่เปลี่ยนแปลงเพราะ (ฉันเดาว่า) Matt รู้สึกติดใจมากกับความคิดของตารางที่น้อยกว่าเขาจะไม่ยอมให้ตัวเองรับรู้ด้านล่างของการจัดทำดัชนีในไบต์ที่ 768 สำคัญ. <sigh>
MikeSchinkel

5

หากปลั๊กอินของคุณจะมีข้อมูลจำนวนมากการใช้wp_postmetaไม่ใช่ความคิดที่ดีดังที่แสดงไว้ด้านล่าง:

ยกตัวอย่าง WooCommerce ในร้านค้าที่มีผลิตภัณฑ์ ~ 30,000 รายการจะมีค่าเฉลี่ยพูด ~ 40 โพสต์เมตา (คุณลักษณะและทุกอย่าง) ต่อผลิตภัณฑ์ภาพผลิตภัณฑ์ 5 ภาพต่อผลิตภัณฑ์ซึ่งหมายความว่าจะมี 4 ภาพเมตา สำหรับแต่ละภาพ:

30,000 ผลิตภัณฑ์ x 40 เมตาละ = 1,200,000 แถว wp_postmeta

+

ผลิตภัณฑ์ 30,000 ภาพ x 5 ภาพเมตาแต่ละภาพ x 4 สำหรับแต่ละ = 600,000 แถว wp_postmeta

ดังนั้นด้วยเพียง 30,000 ผลิตภัณฑ์ที่คุณกำลังมองหาที่มี 1,800,000 wp_postmetaแถวใน

หากคุณเพิ่มคุณสมบัติเพิ่มเติมให้กับผลิตภัณฑ์หรือรูปภาพผลิตภัณฑ์ของคุณหมายเลขนี้จะทวีคูณ

ปัญหาที่เป็นสองเท่า:

  • การเข้าร่วมด้วยตนเองมีราคาแพงมากเมื่อใช้ MySQL
  • wp_postmeta ตารางจะไม่ถูกทำดัชนีเว้นแต่ว่าคุณกำลังใช้เวอร์ชัน mysql ในภายหลัง (เช่นไม่มีดัชนี FULLTEXT สำหรับ meta_value )

ในการให้ตัวอย่างจากกรณีจริง:

SELECT meta_value FROM wp_postmeta WHERE meta_key LIKE '_shipping_city'

การเลือกเมืองที่จัดส่งจากรายละเอียดการสั่งซื้อทั้งหมดจะมาถึงเวลาประมาณ 3 วินาทีในเซิร์ฟเวอร์เฉพาะระดับเริ่มต้นแม้ว่าจะมี 5-10 คำสั่งก็ตาม นี่เป็นเพราะแบบสอบถามถูกเรียกใช้จากwp_postmetaตารางที่มี ~ 3 ล้านแถวในการติดตั้งจริง

แม้กระทั่งโฮมเพจก็ค่อนข้างช้าเพราะธีมดึงองค์ประกอบต่าง ๆ จากwp_postmeta- ตัวเลื่อนส่วนแทรกความเห็นบางส่วนและเมตาอื่น ๆ สองสามตัว ในรายการผลิตภัณฑ์ทั่วไปช้ามากการค้นหาจะช้าในทำนองเดียวกันเมื่อแสดงรายการผลิตภัณฑ์

คุณไม่สามารถแก้ไขได้ด้วยวิธีปกติ คุณสามารถใส่ Elastic Search ในเซิร์ฟเวอร์ของคุณและใช้ Elastic Search plugin ใน Wordpress คุณอาจใช้ redis / memcached คุณอาจใช้หน้าแคชที่ดี แต่ในท้ายที่สุดปัญหาพื้นฐานจะยังคงอยู่ - ดึงข้อมูลจำนวนมากจาก bloatedwp_postmetaตารางจะช้าเมื่อใดก็ตามที่เสร็จสิ้น บนเซิร์ฟเวอร์ที่ฉันทดสอบโซลูชันที่ฉันติดตั้งไว้ด้านล่างทั้งหมดเหล่านี้ได้รับการติดตั้งและกำหนดค่าอย่างเหมาะสมและปรับให้เหมาะสมและไซต์ทำงานได้อย่างสอดคล้องกันตกลงสำหรับผู้ใช้ที่ไม่ได้เข้าสู่ระบบหรือแบบสอบถามที่ทำกันโดยทั่วไป

แต่ช่วงเวลาที่ผู้ใช้ที่เข้าสู่ระบบพยายามที่จะทำสิ่งที่ไม่ได้ทำกันทั่วไปหรือ crons, ปลั๊กอินแคชหรือยูทิลิตี้อื่น ๆ ที่ต้องการดึงข้อมูลจริงจากฐานข้อมูลเพื่อแคชหรือทำสิ่งอื่นใดสิ่งต่าง ๆ ก็ช้าลง

ดังนั้นฉันลองอย่างอื่น:

ฉันเข้ารหัสปลั๊กอินขนาดเล็กเพื่อนำเมตาผลิตภัณฑ์ทั้งหมด (postmeta สำหรับผลิตภัณฑ์ประเภทโพสต์) ไปยังตารางที่กำหนดเองซึ่งสร้างขึ้นโดยรหัส ปลั๊กอินนี้ใช้เมตาทั้งหมดสำหรับแต่ละโพสต์และสร้างตารางโดยเพิ่มเมตาแต่ละรายการเป็นคอลัมน์และแทรกค่าลงในแต่ละแถว ฉันเปลี่ยนรูปแบบ EAV เป็นรูปแบบเชิงสัมพันธ์แนวนอนและแนวราบ ฉันยังมีปลั๊กอินสำหรับลบ postmeta จากผลิตภัณฑ์ที่ถูกย้ายทั้งหมดจากwp_postmetaตาราง

ในขณะที่ฉันอยู่ที่นี่ฉันย้ายสิ่งที่แนบมา postmeta ของและเมตาของโพสต์ประเภทอื่นทั้งหมดไปยังตารางของพวกเขาเอง

จากนั้นฉันก็งุ้มเข้า get_(post_type)_metaกับตัวกรองเพื่อแทนที่การดึงข้อมูลเมตาเพื่อให้บริการจากตารางที่กำหนดเองใหม่

ตอนนี้แบบสอบถามเดียวกันจากก่อนหน้านี้ซึ่งใช้เวลาประมาณ 3 วินาทีในการดึงข้อมูล wp_postmetaใช้เวลา ~ 0.006 วินาที ตอนนี้ไซต์จะทำงานเหมือนกำลังติดตั้ง WP ใหม่

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

โดยธรรมชาติการทำสิ่งต่าง ๆ เป็นวิธีที่ดีกว่า จริงๆแล้วมันเป็นบรรทัดฐาน

อย่างไรก็ตามยังเป็นความรู้ที่ชัดเจนว่าตาราง EAV นั้นไม่มีประสิทธิภาพในการปรับสเกล มีความยืดหยุ่นไม่ จำกัด และให้คุณจัดเก็บข้อมูลใด ๆ แต่ราคาที่คุณจ่ายไปนั้นเป็นประสิทธิภาพ มันเป็นการแลกเปลี่ยนขั้นพื้นฐาน

ในบริบทนั้นมันเป็นการยากที่จะบอกคนที่ตั้งใจจะมีข้อมูลจำนวนมากและ - ห้ามไม่ให้สอบถาม / ค้นหาข้อมูลนั้นเพื่อใช้wp_postmetaตารางอย่างแน่นอน ผลงานยอดเยี่ยมจะยอดเยี่ยม

การใช้ตารางที่กำหนดเองของคุณจะช่วยให้ข้อมูลของคุณซ้อนกันและยังคงเร็วพอ

เช่นเดียวกับที่ Pippin Williams ผู้สร้างโปรแกรมเสริม Easy Digital Downloads กล่าวถึงเขาจะใช้ตารางที่กำหนดเองหากเขาเพิ่งเริ่มเขียนโค้ดปลั๊กอินของเขาหากคุณกำลังจะสร้างบางสิ่งที่จะใช้เป็นระยะเวลานานหรือจัดเก็บข้อมูลจำนวนมาก การใช้ตารางที่กำหนดเองของคุณจะมีประสิทธิภาพมากขึ้นถ้าคุณออกแบบตารางได้ดี

คุณต้องตรวจสอบให้แน่ใจว่าผู้พัฒนาปลั๊กอิน / แอดออนอื่น ๆ มีวิธีการขอเข้าไปในปลั๊กอินของคุณเพื่อจัดการข้อมูลของคุณก่อนและหลังการดึงข้อมูล หากคุณทำเช่นนั้นแสดงว่าคุณแข็งแกร่ง


1
สิ่งที่น่าสนใจ! สิ่งหนึ่งที่ต้องชี้แจงคือตัวกรอง "get_ (post_type) _meta" ที่กล่าวถึงนั้นเรียกว่า "get_ (meta-type) _metadata" โดยที่ meta-type เป็นทั้งโพสต์ความคิดเห็นหรือผู้ใช้ ดังนั้น get_post_meta () จะผ่านตัวกรอง get_post_metadata ไม่ว่าจะเป็นโพสต์ประเภทใด ค่าส่งคืนของตัวกรองคือสิ่งที่คุณต้องการให้ค่าเมตาสุดท้ายเป็น
Berend

get_ (meta-type) _metadata -> ใช้งานได้จริงกับโพสต์ทุกประเภทและฟังก์ชั่นสุดท้ายที่เข้าชมคือ get_post_metadata อย่างไรก็ตามตัวกรองจะทำงานเมื่อคุณใช้อย่างไรก็ตาม
unity100

2

ขึ้นอยู่กับสิ่งที่คุณทำ วิธี WP คือการใช้ตารางที่มีอยู่ตามที่ได้รับการออกแบบมาให้มีความยืดหยุ่นเพียงพออย่างไรก็ตามในบางครั้งคุณจะสามารถเข้าถึงคลาสข้อมูลใหม่ที่ไม่สามารถวางในตารางที่มีอยู่ได้เช่นถ้าคุณต้องการข้อมูลเมตาหมวดหมู่ คุณสามารถเลือกที่จะสร้างตาราง wp_termsmeta

อย่างไรก็ตามโดยปกติคุณสามารถจัดเก็บข้อมูลของคุณได้อย่างสะดวกสบายในตารางต่างๆที่มีอยู่และตำแหน่งที่คุณจัดเก็บข้อมูลของคุณขึ้นอยู่กับสิ่งที่ปลั๊กอินของคุณทำ

  • สำหรับการตั้งค่าปลั๊กอินทั่วไปให้ใช้การเรียก API get_option ()ซึ่งจะถูกแคชด้วย
  • สำหรับปลั๊กอินการตั้งค่าที่โดยเฉพาะอย่างยิ่งกับผู้ที่โพสต์ของแต่ละบุคคลแล้วใช้ข้อมูล meta ที่กำหนดเองต่อโพสต์กับget_post_meta () ซึ่งมักเป็นสิ่งที่คุณต้องการ

การแคชจะดำเนินการภายใน WordPress เพื่อเพิ่มความเร็วในเวลาตอบสนองของคุณ


1

เห็นด้วยกับเดนิส 100% แต่มีวิธีการอยู่รอบ ๆ

ปัญหาเกี่ยวกับการใช้ post meta สำหรับค่าที่จะทำการสอบถามคือเมื่อค่าต่างๆอยู่ในอาร์เรย์เป็นต้นเช่นนี้

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

สิ่งนี้จะถูกเก็บไว้ใน db เป็นสตริงที่ทำให้เป็นอนุกรมซึ่งจะมีลักษณะดังนี้:

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

ดังนั้นเมื่อคุณต้องการค้นหาโพสต์ทั้งหมดด้วย array['key2'] = 'val 2' wp จะต้องดึงทุกรายการเมตาที่เรียกว่าอาเรย์, แกะมันแล้วทดสอบมันแล้วไปที่ถัดไป การทำเช่นนี้จะทำให้เซิร์ฟเวอร์ของคุณผิดหวังหากไซต์ของคุณประสบความสำเร็จและมีโพสต์จำนวนมากหน้าโพสต์ที่กำหนดเอง ฯลฯ

การแก้ปัญหาขึ้นอยู่กับโครงการและคุณจะเห็นว่าทำไม หากคุณต้องการจัดเก็บข้อมูลแบบvar = valwp คุณจะสามารถค้นหาได้โดยไม่ต้องใช้ php เพื่อแกะทุกการทดสอบ ในการทำสิ่งนี้ในสถานการณ์ข้างต้นคุณต้องใช้การกำหนดเนมสเปซและจัดเก็บคีย์เมตา:

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

จากนั้น wp มองหาคีย์ 2 ด้วย val 2 จะสามารถดึงมันได้ทันที นี่คือโครงการขึ้นอยู่กับว่า โครงการปัจจุบันของฉันอาศัย dataTypes ที่แตกต่างกันประมาณ 20 ชนิดเพื่อเก็บไว้ในแต่ละโพสต์ที่กำหนดเองดังนั้นข้างต้นจะสร้างตารางขนาดใหญ่เพื่อค้นหาโดยดูว่าเราคาดหวังว่าโพสต์ 100 พันรายการจะเป็นอย่างไร ดังนั้นในสถานการณ์นั้นตารางที่กำหนดเองจึงเป็นวิธีเดียวเท่านั้น

หวังว่านี่จะช่วยใครซักคน


0

สำหรับไซต์ FarmVille ของฉัน :) ฉันทำทั้งสองอย่าง แต่ไม่เคยทำเสร็จเพราะฉันขายมัน:

  1. ฉันอ่าน Farmville xml และทิ้งข้อมูลในตารางที่กำหนดเอง
  2. ใน WordPress ฉันมีฟิลด์ที่กำหนดเองที่สร้างขึ้นโดยอัตโนมัติสำหรับทุกฟิลด์ในตารางนั้น (และพิเศษ)
  3. ตอนนี้ต้องกังวลว่าจะเกิดอะไรขึ้นหากค่ามีการเปลี่ยนแปลงทั้งในตารางหรือในด้านอื่น ๆ : ฟิลด์ที่กำหนดเองเนื่องจากพวกเขาต้องซิงค์อย่างต่อเนื่อง

ฉันทำสิ่งนี้เพราะฉันต้องการให้ผู้ใช้แก้ไขไซต์เวิร์ดเพรสด้วยการป้อนข้อมูลฟาร์มวิลล์ใหม่เช่น "วัวราคา 10 เหรียญ" แต่จากด้านการบูรณาการ: หากการเปลี่ยนแปลงใน xml จะทำให้วัวมีราคา "20 เหรียญ" (ผ่านปลั๊กอินการแก้ไขส่วนหน้า) ที่จะได้รับเป็นตัวเลือกหลังจากนั้น: เพื่อให้ XML หรือผู้ใช้ถูกต้อง (ระบบเรียงลำดับของ wiki)

นี่คือตัวอย่างเมื่อใช้ทั้งคู่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.