วิธีที่ดีที่สุดในการจัดการแบบสอบถาม SQL ที่เก็บไว้ในรหัสของคุณ? (หรือคุณควร?) [ปิด]


13

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

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

แก้ไข 1 - ฉันสมมติว่าคุณได้แยกมันออกเป็นเลเยอร์โมเดลแล้ว


3
คำถามนี้เหมาะสมอย่างแน่นอนที่นี่ - การจัดระเบียบโค้ด: 'สร้างแรงบันดาลใจ [s] คำตอบที่อธิบาย "ทำไม" และ "อย่างไร" และเป็นของ 'รูปแบบการออกแบบ' และ 'สถาปัตยกรรม' ของอาสาสมัคร (จากคำถามที่พบบ่อย )
Michael K

1
ฉันเพิ่งจะถามคำถามเดียวกันนี้ ฉันหวังว่าจะมีคำตอบเพิ่มเติมที่นี่
Michael Kristofik

คำตอบ:


10

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

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

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

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

GetValue(SQL, [transaction], [array_of_params])
GetRow(SQL, [transaction], [array_of_params])
GetRowList(SQL, [transaction], [array_of_params])
GetValueList(SQL, [transaction], [array_of_params])
Execute(SQL, [transaction], [array_of_params])

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

โดยสรุปถือว่า SQL เป็นส่วนหนึ่งของการเขียนโปรแกรมและไม่เป็นนามธรรมเพื่อประโยชน์ของนามธรรม


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

1
"ไม่เป็นนามธรรมเพื่อประโยชน์ของนามธรรม" - จุดดี บทคัดย่อเพื่อประโยชน์ของรหัสที่เข้าใจได้มากขึ้น
Jason Baker

'เคล็ดลับก็คือการมีวิธีการสืบค้นฐานข้อมูลที่ดีจริง ๆ ': ฉันเห็นด้วยอย่างแน่นอน ช่วยได้มากเมื่อมีที่เดียวในการแก้ไขโค้ดเมื่อการเปลี่ยนแปลงตรรกะทางธุรกิจ
Michael K

1
คุณใส่ SQL ไว้ที่ไหน? มันรวบรวมไว้ในแอปพลิเคชันและส่งโดยใช้วิธีการด้านบนหรือไม่
johnny

จากความคิดเห็นของ OP โดยคำตอบของ Jason Baker "การจ้องมองบาร์เรลของแบบสอบถาม SQL ยักษ์ ... " วิธีนี้แก้ไขปัญหาในการอ่านบล็อก SQL ข้อความขนาดใหญ่ได้อย่างไร
JeffO

0

โดยทั่วไปแล้วการมีเลเยอร์โมเดลแยกต่างหากเป็นวิธีที่ดีที่สุด มีรูปแบบการออกแบบองค์กรจำนวนมากที่ให้วิธีการออกแบบสิ่งนี้


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

2
@ jellyfishtree - ฉันเกรงว่าฉันจะไม่เข้าใจว่าปัญหาคืออะไร ฉันหมายความว่าคุณกลัวว่าเลเยอร์โมเดลของคุณอาจจบลงด้วยโค้ดโมเดลมากเกินไปหรือไม่?
Jason Baker

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

0

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

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

เอนทิตีย่อบทคัดย่อชื่อเขตข้อมูลตารางตารางจริงด้วย getters และ setters อาจมีการแปลงข้อมูลบางอย่างระหว่างประเภทและประเภทของเขตข้อมูลฐานข้อมูลที่มีอยู่ในภาษาแอปพลิเคชัน / การเขียนโปรแกรมของคุณ ถ้า ORM ของคุณรองรับสิ่งนั้น - เอนทิตีอาจจัดการกับการเชื่อมโยง

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

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