ทำไมฐานข้อมูลเชิงสัมพันธ์ไม่สนับสนุนข้อมูลที่ส่งคืนในรูปแบบที่ซ้อนกัน?


46

สมมติว่าฉันกำลังสร้างบล็อกที่ฉันต้องการโพสต์และแสดงความคิดเห็น ดังนั้นฉันจึงสร้างสองตารางตาราง 'โพสต์' ที่มีคอลัมน์ 'id' จำนวนเต็มโดยอัตโนมัติและตาราง 'ความคิดเห็น' ที่มีคีย์ต่างประเทศ 'post_id'

จากนั้นฉันต้องการเรียกใช้สิ่งที่อาจเป็นคิวรีที่พบบ่อยที่สุดของฉันซึ่งก็คือเรียกโพสต์และความคิดเห็นทั้งหมด ค่อนข้างใหม่สำหรับฐานข้อมูลเชิงสัมพันธ์วิธีที่ปรากฏชัดเจนที่สุดสำหรับฉันคือการเขียนแบบสอบถามที่มีลักษณะดังนี้:

SELECT id, content, (SELECT * FROM comments WHERE post_id = 7) AS comments
FROM posts
WHERE id = 7

ซึ่งจะให้ ID และเนื้อหาของโพสต์ที่ฉันต้องการพร้อมกับแถวความคิดเห็นที่เกี่ยวข้องทั้งหมดที่บรรจุอย่างเป็นระเบียบในอาร์เรย์ (การแสดงแบบซ้อนที่คุณต้องการใช้ใน JSON) แน่นอนว่า SQL และฐานข้อมูลเชิงสัมพันธ์ไม่ทำงานเช่นนี้และสิ่งที่ใกล้เคียงที่สุดที่พวกเขาจะได้รับก็คือการเข้าร่วมระหว่าง 'โพสต์' และ 'ความคิดเห็น' ซึ่งจะส่งคืนข้อมูลซ้ำซ้อนที่ไม่จำเป็นจำนวนมาก ในทุก ๆ แถว) ซึ่งหมายความว่าเวลาในการประมวลผลจะถูกใช้ทั้งในฐานข้อมูลเพื่อรวมเข้าด้วยกันและบน ORM ของฉันเพื่อแยกวิเคราะห์และเลิกทำทั้งหมด

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

ฉันเข้าใจว่าฐานข้อมูลเชิงสัมพันธ์เป็นเทคโนโลยีที่ได้รับการพิสูจน์แล้ว (นรกพวกเขามีอายุมากกว่าฉัน) และมีการวิจัยมากมายที่รวบรวมไว้ในทศวรรษที่ผ่านมาและฉันแน่ใจว่ามีเหตุผลที่ดีจริงๆที่ทำให้พวกเขา (และ มาตรฐาน SQL) ได้รับการออกแบบให้ทำงานในแบบที่พวกเขาทำ แต่ฉันไม่แน่ใจว่าทำไมวิธีที่ฉันระบุไว้ข้างต้นเป็นไปไม่ได้ ดูเหมือนว่าฉันจะเป็นวิธีที่ง่ายและชัดเจนที่สุดในการสร้างความสัมพันธ์ขั้นพื้นฐานที่สุดระหว่างบันทึก ทำไมฐานข้อมูลเชิงสัมพันธ์ไม่เสนออะไรแบบนี้?

(ข้อจำกัดความรับผิดชอบ: ฉันมักจะเขียน webapps โดยใช้ Rails และ NoSQL datastores แต่เมื่อเร็ว ๆ นี้ฉันได้ลองใช้ Postgres และฉันชอบมันมากจริง ๆ ฉันไม่ได้ตั้งใจจะโจมตีฐานข้อมูลเชิงสัมพันธ์ฉันแค่สับสน)

ฉันไม่ได้ถามวิธีเพิ่มประสิทธิภาพแอพ Rails หรือวิธีแฮ็กวิธีแก้ปัญหานี้ในฐานข้อมูลเฉพาะ ฉันถามว่าทำไมมาตรฐาน SQL ทำงานด้วยวิธีนี้เมื่อดูเหมือนว่าใช้ง่ายและสิ้นเปลืองกับฉัน ต้องมีเหตุผลทางประวัติศาสตร์ว่าทำไมผู้ออกแบบดั้งเดิมของ SQL ต้องการให้ผลลัพธ์ของพวกเขาเป็นเช่นนี้


1
ไม่ใช่ orms ทั้งหมดทำงานอย่างนั้น hibernate / nhibernate อนุญาตให้ระบุการรวมและสามารถโหลดต้นไม้วัตถุทั้งหมดจากแบบสอบถามเดียว
ธานกอนซาเลซ

1
ในขณะที่เป็นจุดที่น่าสนใจของการสนทนาฉันไม่แน่ใจว่านี่เป็นคำตอบที่แท้จริงโดยไม่ต้องประชุมกับผู้ชาย ansi sql
nathan gonzalez

@nathan: ใช่ไม่ใช่ทั้งหมด ฉันใช้Sequelซึ่งช่วยให้คุณเลือกวิธีที่คุณต้องการสำหรับคิวรีที่ระบุ ( docs ) แต่พวกเขายังคงสนับสนุนแนวทางการค้นหาหลายครั้ง (ด้วยเหตุผลด้านประสิทธิภาพฉันคิดว่า)

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

1
พวกเขาเห็นว่าxml
Ian

คำตอบ:


42

CJ วันเข้าไปในรายละเอียดเกี่ยวกับเรื่องนี้ในบทที่ 7 และภาคผนวก B ของSQL และทฤษฎีสัมพันธ์ คุณพูดถูกไม่มีทฤษฎีเชิงความสัมพันธ์ใดที่ห้ามประเภทข้อมูลของแอตทริบิวต์จากการเป็นความสัมพันธ์ตราบใดที่มันเป็นความสัมพันธ์แบบเดียวกันในทุกแถว ตัวอย่างของคุณจะมีคุณสมบัติ

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

ข้อความค้นหาข้อ จำกัด และการอัปเดตมีความซับซ้อนยากต่อการเขียนและยากขึ้นสำหรับ RDBMS ที่จะสนับสนุนหากคุณอนุญาตแอตทริบิวต์ที่มีค่าความสัมพันธ์ (RVA)

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

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

จากสิ่งที่ฉันเข้าใจ (ฉันไม่ได้ใช้) RelและDataphorเป็นโครงการ RDBMS ที่สนับสนุนแอตทริบิวต์ที่มีค่าความสัมพันธ์


ความคิดเห็นอีกครั้งจาก @dportas:

ประเภทที่มีโครงสร้างเป็นส่วนหนึ่งของ SQL-99 และ Oracle รองรับสิ่งเหล่านี้ แต่จะไม่เก็บสิ่งอันดับหลาย ๆ ตัวไว้ในตารางที่ซ้อนกันต่อแถวของตารางพื้นฐาน ตัวอย่างทั่วไปคือแอตทริบิวต์ "ที่อยู่" ซึ่งดูเหมือนจะเป็นคอลัมน์เดียวของตารางฐาน แต่มีคอลัมน์ย่อยเพิ่มเติมสำหรับถนนเมืองรหัสไปรษณีย์ ฯลฯ

Oracle สนับสนุนตารางที่ซ้อนกันและสิ่งเหล่านี้อนุญาตให้มีสิ่งอันดับหลาย ๆ ต่อแถวของตารางฐาน แต่ฉันไม่ทราบว่านี่เป็นส่วนหนึ่งของ SQL มาตรฐาน และอย่าลืมข้อสรุปของหนึ่งบล็อก: "ฉันจะไม่ใช้ตารางที่ซ้อนกันในคำสั่ง CREATE TABLE คุณใช้เวลาตลอดเวลาในการยกเลิกการซ้อนเพื่อทำให้มีประโยชน์อีกครั้ง!"


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

ชุดผลลัพธ์และตารางเป็นชนิด วันที่เรียกมันว่าสัมพันธ์และrelvarsตามลำดับ (โดยการเปรียบเทียบ 42 เป็นจำนวนเต็มในขณะที่ตัวแปรxสามารถมีค่าเป็นจำนวนเต็ม 42) การดำเนินการเดียวกันนี้ใช้กับความสัมพันธ์และ relvars ดังนั้นโครงสร้างของพวกเขาจึงต้องสอดคล้องกัน
Bill Karwin

2
SQL มาตรฐานสนับสนุนตารางที่ซ้อนกัน พวกเขาจะเรียกว่า "ประเภทโครงสร้าง" Oracle เป็นหนึ่งใน DBMS ที่มีคุณสมบัตินี้
nvogel

2
มันไม่มีเหตุผลหรือเปล่าที่จะโต้แย้งว่าเพื่อหลีกเลี่ยงการทำซ้ำข้อมูลคุณต้องเขียนแบบสอบถามของคุณในลักษณะที่ซ้ำซ้อน
Eamon Nerbonne

1
@EamonNerbonne สมมาตรของการดำเนินการเชิงสัมพันธ์ ตัวอย่างเช่นการฉาย หากฉันเลือกแอตทริบิวต์ย่อยบางส่วนจาก RVA ฉันจะใช้การดำเนินการย้อนกลับกับชุดผลลัพธ์เพื่อสร้างลำดับชั้นดั้งเดิมได้อย่างไร ฉันพบหน้าหน้า 293 ของหนังสือเล่มวันอยู่ใน Google หนังสือดังนั้นคุณสามารถดูสิ่งที่เขาเขียน: books.google.co.th/…
Bill Karwin

15

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

ยังมีตัวอย่างบางส่วนของระบบฐานข้อมูลแบบลำดับชั้นใน wild โดยเฉพาะ windows registry และ LDAP

ครอบคลุมเรื่องนี้อย่างกว้างขวางในบทความต่อไปนี้


10

ฉันคิดว่าคำถามของคุณมีศูนย์กลางอยู่ที่ข้อเท็จจริงที่ว่าในขณะที่ฐานข้อมูลอยู่บนพื้นฐานของตรรกะที่มั่นคงและตั้งพื้นฐานทางทฤษฎีและพวกเขาจัดเก็บงานที่ดีมากจัดการและดึงข้อมูลในชุด (2 มิติ) ในขณะที่มั่นใจความสมบูรณ์ของการอ้างอิง และอื่น ๆ อีกมากมายพวกเขาไม่ได้ให้คุณสมบัติ (เพิ่มเติม) ในการส่ง (และรับ) ข้อมูลในสิ่งที่เราสามารถเรียกรูปแบบเชิงวัตถุหรือรูปแบบลำดับชั้น

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

ฉันไม่เห็นสิ่งใดที่ไม่มีประสิทธิภาพในการส่ง 2 ข้อความค้นหาและรับผลลัพธ์ 2 ชุดด้วย:

--- Query-1-posts
SELECT id, content 
FROM posts
WHERE id = 7


--- Query-2-comments
SELECT * 
FROM comments 
WHERE post_id = 7

ฉันขอยืนยันว่า (เกือบ) วิธีที่มีประสิทธิภาพมากที่สุด (เกือบเพราะคุณไม่ต้องการposts.idและไม่ใช่คอลัมน์ทั้งหมดcomments.*)

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

ฉันไม่สามารถพูดเกี่ยวกับ ORM ได้จริงๆ แต่บางทีพวกเขาบางคนสามารถทำหน้าที่นี้ให้เราได้

เทคนิคที่คล้ายกันสามารถใช้ในการส่งข้อมูลระหว่างเว็บเซิร์ฟเวอร์และไคลเอนต์ มีการใช้เทคนิคอื่น ๆ (เช่นการแคช) ดังนั้นฐานข้อมูล (หรือเว็บหรือเซิร์ฟเวอร์อื่น ๆ ) จะไม่โหลดมากเกินไปเมื่อมีคำขอซ้ำกัน

ฉันเดาว่ามาตรฐานเช่น SQL นั้นดีที่สุดหากพวกเขามีความเชี่ยวชาญในด้านเดียวและไม่พยายามครอบคลุมทุกสาขา

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


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

2
@Precious: ไม่จำเป็นต้องมีค่าใช้จ่ายที่เพิ่มขึ้นสำหรับการเรียกใช้หลายแบบสอบถาม ฐานข้อมูลส่วนใหญ่อนุญาตให้คุณส่งแบบสอบถามหลายรายการในชุดเดียวและรับหลายชุดผลลัพธ์จากแบบสอบถามเดียว
Daniel Pryden

@PreciousBodilyFluids - ตัวอย่าง SQL ในคำตอบของ ypercube เป็นแบบสอบถามเดียวซึ่งจะถูกส่งในการเรียกฐานข้อมูลเดียวและส่งกลับสองชุดผลลัพธ์ในการตอบสนองเดียว
Carson63000

5

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


5

ฉันรู้ว่าอย่างน้อย SQLServer รองรับการสืบค้นซ้อนเมื่อคุณใช้สำหรับ XML

SELECT id, content, (SELECT * FROM comments WHERE post_id = posts.id FOR XML PATH('comments'), TYPE) AS comments
FROM posts
WHERE id = 7
FOR XML PATH('posts')

ปัญหาที่นี่ไม่ใช่การขาดการสนับสนุนจาก RDBMS แต่ขาดการสนับสนุนตารางที่ซ้อนกันในตาราง

นอกจากสิ่งที่ห้ามไม่ให้คุณใช้การเข้าร่วมภายใน

SELECT id, content, comments.*
FROM posts inner join comments on comments.post_id = posts.id
WHERE id = 7

คุณสามารถดูการรวมภายในเป็นตารางที่ซ้อนกันได้เฉพาะเนื้อหาของ 2 ฟิลด์แรกเท่านั้นที่สามารถทำซ้ำได้ ฉันไม่ต้องกังวลเกี่ยวกับประสิทธิภาพของการเข้าร่วมมากนักส่วนที่ช้าในแบบสอบถามเช่นนี้คือ io จากฐานข้อมูลไปยังไคลเอนต์ นี่จะเป็นปัญหาเมื่อเนื้อหามีข้อมูลจำนวนมาก ในกรณีที่ว่าผมจะแนะนำให้ทั้งสองคำสั่งหนึ่งที่มีและเป็นหนึ่งเดียวกับภายในเข้าร่วมและselect id, content select posts.id, comments.*สิ่งนี้จะปรับขยายได้แม้จะมีการโพสต์หลายโพสต์เนื่องจากคุณจะยังคงใช้การค้นหา 2 รายการเท่านั้น


คำถามที่อยู่นี้ ไม่ว่าคุณจะต้องเดินทางไปกลับสองครั้ง (ไม่เหมาะสมที่สุด) หรือคุณต้องส่งคืนข้อมูลที่ซ้ำซ้อนในสองคอลัมน์แรก (เช่นเดียวกับที่ไม่เหมาะสม) เขาต้องการทางออกที่ดีที่สุด (ไม่ใช่ความจริงในความคิดของฉัน)
Scott Whitlock

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

5

ที่จริงแล้วออราเคิลรองรับสิ่งที่คุณต้องการ แต่คุณจำเป็นต้องห่อคำสืบค้นย่อยด้วยคีย์เวิร์ด "เคอร์เซอร์" ผลลัพธ์ถูกดึงผ่านเคอร์เซอร์ที่เปิดอยู่ ใน Java ตัวอย่างเช่นความคิดเห็นจะปรากฏขึ้นเป็นชุดผลลัพธ์ ข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้ดูเอกสารของ Oracle เกี่ยวกับ"CURSOR Expression"

SELECT id, content, cursor(SELECT * FROM comments WHERE post_id = 7) AS comments
FROM posts
WHERE id = 7

1

บางคนสนับสนุนการซ้อน (แบบลำดับชั้น)

หากคุณต้องการหนึ่งแบบสอบถามคุณสามารถมีหนึ่งตารางที่ตนเองอ้างอิงเอง RDMS บางรุ่นรองรับแนวคิดนี้ ตัวอย่างเช่นกับ SQL Server หนึ่งสามารถผู้ใช้ Common Table Expressions (CTEs) สำหรับแบบสอบถามแบบลำดับชั้น

ในกรณีของคุณโพสต์จะอยู่ที่ระดับ 0 จากนั้นความคิดเห็นทั้งหมดจะอยู่ที่ระดับ 1

ตัวเลือกอื่นคือ 2 ข้อความค้นหาหรือเข้าร่วมกับข้อมูลพิเศษบางอย่างสำหรับทุกระเบียนที่ส่งคืน (ที่คนอื่นพูดถึง)

ตัวอย่างของลำดับชั้น:

https://stackoverflow.com/questions/14274942/sql-server-cte-and-recursion-example

ในลิงค์ด้านบน EmpLevel แสดงระดับของการซ้อน (หรือลำดับชั้น)


ฉันไม่พบเอกสารเกี่ยวกับชุดผลลัพธ์ย่อยใน SQL Server แม้ในขณะที่ใช้ CTE โดย resultset ฉันหมายถึงแถวของข้อมูลที่มีคอลัมน์ที่พิมพ์มากพอ คุณสามารถเพิ่มการอ้างอิงไปยังคำตอบของคุณ?
SandRock

@SandRock - ฐานข้อมูลจะส่งกลับชุดผลลัพธ์เดียวกลับมาจากแบบสอบถาม SQL ด้วยการระบุระดับในแบบสอบถามคุณสามารถสร้างชุดผลลัพธ์แบบลำดับชั้นหรือซ้อนกันที่จะประมวลผลได้ ฉันคิดว่าในปัจจุบันนั้นใกล้เคียงที่สุดแล้วเราจะ gonig กลับไปหาข้อมูลที่ซ้อนกันอยู่
Jon Raynor

0

ฉันขอโทษฉันไม่แน่ใจว่าฉันเข้าใจปัญหาของคุณอย่างแน่นอน

ใน MSSQL คุณสามารถรันคำสั่ง SQL 2 คำสั่งได้

SELECT id, content
FROM posts
WHERE id = 7

SELECT * FROM comments WHERE post_id = 7

และจะส่งคืนผลลัพธ์ 2 ชุดพร้อมกัน


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

แต่มันจะเป็นการเดินทางไปกลับหนึ่งครั้ง stackoverflow.com/questions/2336362/…
Biff MaGriff

0

RDBMs ตั้งอยู่บนพื้นฐานของทฤษฎีและพวกเขายึดติดกับทฤษฎี สิ่งนี้ทำให้ความสอดคล้องที่ดีและความน่าเชื่อถือที่ได้รับการพิสูจน์ทางคณิตศาสตร์

เนื่องจากรูปแบบนั้นง่ายและอยู่บนพื้นฐานของทฤษฎีอีกครั้งทำให้ผู้คนสามารถเพิ่มประสิทธิภาพและใช้งานได้ง่าย ซึ่งแตกต่างจาก NoSQL ที่ทุกคนทำแตกต่างกันเล็กน้อย

มีความพยายามในอดีตที่จะสร้างฐานข้อมูลแบบลำดับชั้น แต่ IIRC (ดูเหมือนจะไม่ google) มีปัญหา (รอบและความเสมอภาคมาถึงใจ)


0

คุณมีความต้องการเฉพาะ มันจะดีกว่าที่จะดึงข้อมูลออกจากฐานข้อมูลในรูปแบบที่คุณต้องการเพื่อให้คุณสามารถทำสิ่งที่คุณต้องการ

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

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

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


0

ในความคิดของฉันส่วนใหญ่เป็นเพราะ SQL และวิธีดำเนินการแบบสอบถามรวม - ฟังก์ชั่นรวมและการจัดกลุ่มจะดำเนินการใน rowets 2 มิติขนาดใหญ่เพื่อส่งคืนผลลัพธ์ นั่นเป็นวิธีที่เป็นมาตั้งแต่เริ่มต้นและเป็นไปอย่างรวดเร็วมาก (โซลูชัน NoSQL ส่วนใหญ่ค่อนข้างช้ากับการรวมและพึ่งพา schema denormalized แทนการค้นหาที่ซับซ้อน)

แน่นอน PostgreSQL มีคุณสมบัติบางอย่างจากฐานข้อมูลเชิงวัตถุ ตามอีเมลนี้ ( ข้อความ ) คุณสามารถบรรลุสิ่งที่คุณต้องการโดยการสร้างการรวมที่กำหนดเอง

โดยส่วนตัวแล้วฉันใช้เฟรมเวิร์กเช่น Doctrine ORM (PHP) ซึ่งทำหน้าที่รวมแอพพลิเคชั่นด้านข้างและฟีเจอร์สนับสนุนเช่น lazy-loading เพื่อเพิ่มประสิทธิภาพ


0

PostgreSQL ไม่สนับสนุนความหลากหลายของประเภทข้อมูลที่มีโครงสร้างรวมทั้งอาร์เรย์และJSON การใช้ SQL หรือหนึ่งในภาษาเชิงโพรซีเดอร์แบบฝังคุณสามารถสร้างค่าด้วยโครงสร้างที่ซับซ้อนตามอำเภอใจและส่งกลับไปยังแอปพลิเคชันของคุณ คุณยังสามารถสร้างตารางที่มีคอลัมน์ประเภทที่มีโครงสร้างใด ๆ ได้แม้ว่าคุณจะต้องพิจารณาอย่างรอบคอบว่าคุณออกแบบการออกแบบของคุณโดยไม่จำเป็นหรือไม่


1
นี้ไม่ได้ดูเหมือนจะนำเสนออะไรที่สำคัญกว่าจุดทำและอธิบายในก่อน 13 คำตอบ
ริ้น

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