ทางเลือก EAV สำหรับฟิลด์แบบไดนามิกในคลังข้อมูลสคีมา


13

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

เช่น http://example.com/?action=test&foo=abc&bar=def...

ฉันต้องเก็บการfield => valueแมปทั้งหมดเช่น(action => test), (foo => abc), (bar => def)และเนื่องจากฟิลด์นั้นเป็นแบบไดนามิกวิธีแก้ปัญหาเดียวที่ฉันได้พบคือการใช้เอนทิตี - แอตทริบิวต์ - ค่า - อย่างไรก็ตามผู้คนพูดว่ามันเป็นการออกแบบที่แย่มาก

ดังนั้นให้พิจารณากรณีการใช้งานของฉันด้านบนสิ่งที่จะเป็นทางเลือกที่เหมาะสมกับ EAV?

สคีมาปัจจุบันของฉันโดยใช้ KAV

  1. ตารางrequests
    (id, timestamp, uri)
    เช่น(1, 149382220, '/')

  2. ตารางparams
    (request_id, key, value)
    เช่น(1, 'action', 'test'), (1, 'foo', 'abc'), (1, 'bar', 'def')

ข้อเสนอแนะใด ๆ

อัปเดต: เราเรียกใช้คลังสินค้าใน AWS RedShift


2
มีอะไรผิดปกติในการลองสิ่งที่คุณกำลังแนะนำบนฐานข้อมูล dev นอกจากนี้คุณกำลังพูดถึง SQL Server? SQLแท็กเป็นวงกว้างสวย
Max Vernon

อัปเดตคำถามของฉัน
Howard

1
คุณใช้ DBMS รุ่นใดอยู่ บางคนมีความสามารถในการจัดทำดัชนีข้อความที่ดีดังนั้นฉันจะไม่ออกกฎโดยใช้ฟิลด์ "ข้อความยาว" เพื่อจัดเก็บคำขอ ต้องบอกว่าฉันจะไม่มีปัญหาในการใช้แบบจำลองที่คุณเสนอ ในขณะที่ EAV ในความหมายที่เข้มงวดมันถูกใช้เพื่อจุดประสงค์เฉพาะอย่างนี้เท่านั้น อีกครั้งเมื่อพูดถึงสิ่งที่คุณต้องทำแบบสอบถามประเภทใด ลองและเขียนข้อความค้นหาเหล่านี้กับรุ่นนี้เพื่อดูว่าเหมาะกับคุณหรือไม่
Colin 't Hart

1
คุณใช้ RDBMS รุ่นใดอยู่ SQLไม่เจาะจงพอ คุณถูกถามสองครั้ง ฉันเป็นคนที่สาม
Erwin Brandstetter

2
เนื่องจาก RedShift เป็นไปตาม PostgreSQL ฉันจะพยายามใช้hstoreหรือjsonประเภทข้อมูล (หรือjsonbถ้า / เมื่อพวกเขา "อัพเกรด" เป็น 9.4)
Colin 't Hart

คำตอบ:


11

ฉันสามารถคิดถึงวิธีแก้ปัญหาสามข้อ ได้แก่ EAV, XML และ Sparse Columns หลังเป็นแบบเฉพาะผู้ขายและอาจไม่เป็นประโยชน์กับคุณ

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

ข้อควรพิจารณาเกี่ยวกับ EAV

EAV / KVS ตามที่คุณได้อธิบายไว้ข้างต้นมีแนวโน้มที่จะนำไปใช้งานได้อย่างตรงไปตรงมาที่สุด

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

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

XML

ระบบฐานข้อมูลองค์กรส่วนใหญ่ให้การจัดการ XML ที่สมบูรณ์มากรวมถึงการตรวจสอบความถูกต้องการทำดัชนีและการสืบค้นที่ซับซ้อน

การโหลดคำขอ API ลงในฐานข้อมูลเป็น XML จะให้หนึ่ง tuple ต่อคำขอซึ่งในทางตรรกะอาจเป็นที่พอใจมากกว่าที่คุณมีจำนวนแถวที่ไม่รู้จักในตาราง EAV

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

ข้อเสียที่ใหญ่ที่สุดคือนี่อาจเป็นวิธีเดียวในการจัดการข้อมูลที่ซับซ้อนกว่าการจัดการสตริงของคำขอต้นฉบับ!

คอลัมน์กระจัดกระจาย / ตารางแบบดั้งเดิม

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

คุณลักษณะSparse Columnsของ SQL Server เป็นทางเลือกที่ยอดเยี่ยมในการจัดเก็บ EAV ตารางที่มีคอลัมน์ที่กระจัดกระจายจะทำงานเหมือนกับตารางปกติยกเว้นว่าสามารถมีคอลัมน์ได้มากถึง 30,000 คอลัมน์และค่า NULL ในคอลัมน์ที่กระจายอยู่นั้นจะไม่มีที่ว่างในตาราง

การรวมเข้ากับดัชนีตัวกรอง (คุณลักษณะเฉพาะของเซิร์ฟเวอร์ SQL อื่น) สามารถเป็นทางเลือกที่มีประสิทธิภาพอย่างยิ่งในการจัดเก็บ EAV หากคุณมักจะสอบถามคอลัมน์และ / หรือค่าบางคอลัมน์

การใช้ตารางแบบดั้งเดิมกับผู้จำหน่ายรายอื่นอาจใช้งานได้ - IBM สนับสนุนมากกว่า 700 คอลัมน์ต่อตารางและ Oracle ประมาณ 1,000 รายการและคุณลักษณะต่าง ๆ เช่นการบีบอัดหรือการปฏิบัติต่อท้าย nulls ของ Oracle อาจหมายความว่าคุณสามารถจัดเก็บข้อมูล API ได้อย่างมีประสิทธิภาพ

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


2
ใน PostgreSQL ฉันจะไม่แนะนำ XML แต่อย่างใดอย่างหนึ่งหรือhstore jsonในอีก 9.4 jsonbจะเป็นคำแนะนำของฉัน
Colin 't Hart

ฉันชอบคำตอบนี้กับข้อดีข้อเสียและคำอธิบายของแต่ละคน มีข้อมูลมาก - ฉันขอขอบคุณข้อมูล Sparse Columns ฉันต้องการตัวอย่างของ EAV โดยใช้วิธีกระจายคอลัมน์
StixO

9

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

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

ตัวอย่างเช่นในที่สุดฉันก็มีตารางสำหรับข้อมูลผู้อ้างอิงหนึ่งรายการสำหรับข้อมูลคำขอเป้าหมายและอีกหนึ่งรายการสำหรับรายการที่เกี่ยวข้องกับผู้ใช้เช่นคำค้นหาที่ป้อน

ฉันพบความสามารถในการจัดเก็บสตริงข้อความค้นหาทั้งหมดในตารางเดียวเป็นหยดในขณะที่ให้ความสามารถในการแยกหยดนั้นออกจากกันในอนาคตพบความต้องการของฉันได้เป็นอย่างดี


1
ทั้งคำถามและคำตอบคำBLOBนี้ใช้ซึ่งหมายถึงBinary Long OBject ฉันต้องการใช้CLOB(Character Long OBject) หรืออะไรทำนองนั้นtextใน PostgreSQL เนื่องจากเรากำลังพูดถึงตัวละครไม่ใช่ข้อมูลไบนารี่
Colin 't Hart

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