ขั้นตอนการจัดเก็บวิธีปฏิบัติที่ไม่ดีที่หนึ่งใน บริษัท ที่ปรึกษาด้านไอทีรายใหญ่ที่สุดในโลก?


148

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

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

เรากำลังพัฒนาแอพที่ซับซ้อนโดยใช้วิธีการพัฒนาซอฟต์แวร์ Agile ทุกคนคิดเหตุผลที่ดีว่าทำไมพวกเขาไม่ต้องการใช้ procs ที่เก็บไว้? ฉันเดาว่า DBAs ไม่ต้องการรักษา procs ที่เก็บไว้ แต่ดูเหมือนว่าจะมีวิธีเชิงลบมากเกินไปที่จะพิสูจน์การตัดสินใจในการออกแบบ


3
มันใช้รหัสอะไรซ้ำเพิ่ม? จะเกิดอะไรขึ้นถ้าไคลเอ็นต์ของคุณใช้ฐานข้อมูลอื่น ต้องทิ้ง SPs เหล่านั้นทั้งหมดและเริ่มต้นจากศูนย์ อย่าปกป้องคุณจากการฉีด sql ความเร็วนั้นน้อยมากในกรณีส่วนใหญ่
Rig

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

1
@Rig Code นำมาใช้ใหม่จะถูกเพิ่มเช่นเดียวกับฟังก์ชั่นของภาษาใด ๆ - โดยการห่อรหัสในภาชนะที่นำมาใช้ใหม่ แน่นอนว่าขั้นตอนการจัดเก็บจริง ๆ แล้วปกป้องคุณจากการฉีด SQL ตราบใดที่คุณไม่เรียกใช้งานสตริงที่คุณสร้างขึ้น การบอกความเร็วนั้นน้อยมากดูเหมือนว่าจะไม่ได้รับการศึกษา กรณีส่วนใหญ่จะไม่ตกอยู่ในหมวดหมู่เดียวกันกับผลประโยชน์ด้านประสิทธิภาพ แต่แสดงความแตกต่างอย่างกว้างขวาง
Garet Claborn

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

2
มาจากพื้นหลังที่เราใช้ sps เกือบพิเศษฉันสามารถบอกคุณได้ประโยชน์จากการย้ายออกจากพวกเขาและใช้ ORM เช่น Entity Framework หลายครั้งที่ตรรกะทางธุรกิจได้รับการสรุปในกระบวนการ ในขณะที่คุณสามารถรุ่น procs กับงานและเครื่องมือของบุคคลที่สาม มันไม่ง่ายอย่างที่ควรจะทำในกรอบเช่น TFS หรือ GIT รหัสฐานข้อมูลของคุณที่ปล่อยออกมานั้นไม่เชื่อเรื่องผู้ให้บริการ RDBMS ของคุณ ดังนั้นคุณสามารถเปลี่ยนผู้ให้บริการ RDBMS ในภายหลังโดยไม่ต้องปวดหัว
ewahner

คำตอบ:


280

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

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


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

12
@kevin cline: กำหนด "รัฐที่ไม่สอดคล้องกัน" ฉันยอมรับว่าฟีเจอร์ DB เช่น Referential Integrity นั้นมีค่าและลดโอกาสในการเกิดข้อผิดพลาดของแอปพลิเคชันอย่างมากซึ่งก่อให้เกิดความเสียหายร้ายแรง อย่างไรก็ตามโดยทั่วไปแล้วคำจำกัดความของ "ข้อมูลที่สอดคล้องกัน" นั้นขึ้นอยู่กับการดำเนินการตามกฎเกณฑ์ทางธุรกิจที่ถูกต้อง
Eric J.

16
เพิ่มล้านของฉันเป็นล้านของ Mayo ตรรกะทางธุรกิจแบบกระจายจะนำคุณออกจากเส้นทางแห่งการฝึกฝนที่ดีตรงไปยังช่องทางแห่งความวิกลจริต
นิโก้

27
+1 ตรรกะทางธุรกิจที่เข้ามาใน DAL เป็นเรื่องที่น่ากังวลอย่างยิ่ง
ระบบ

30
@ChristopherMahan ฉันไม่ต้องการใช้ฐานข้อมูลที่คุณออกแบบ นั่นคือวิธีปฏิบัติที่เลวร้ายที่สุดที่เป็นไปได้จากมุมมองฐานข้อมูล ฐานข้อมูลมักได้รับผลกระทบโดยตรงที่ฐานข้อมูล สายตาสั้นคิดว่าจะมีคนใช้เลเยอร์ธุรกิจเพื่ออัปเดตบันทึกกว่าล้านรายการหรือสิ่งอื่น ๆ ที่เกิดขึ้นเมื่อเวลาผ่านไป การนำเข้าไม่ได้ผ่านเลเยอร์ธุรกิจโดยทั่วไป (ใช่ฉันต้องการประมวลผลระเบียน 21 ล้านรายการของฉันนำเข้าหนึ่งระเบียนในแต่ละครั้งในชั้นธุรกิจ) การฉ้อโกงนั้นง่ายกว่ามากเมื่อคุณไม่มีข้อ จำกัด ในระดับฐานข้อมูล ข้อมูลที่ไม่ดีเกือบ 100% แน่นอน
HLGEM

163

ข้อสังเกตบางอย่าง

ขั้นตอนการจัดเก็บให้คุณนำรหัสมาใช้ใหม่และการห่อหุ้ม (สองเสาหลักของการพัฒนาซอฟต์แวร์)

เฉพาะในกรณีที่คุณใช้อย่างถูกต้องในบริบทที่ควรใช้งาน การอ้างสิทธิ์เดียวกันสามารถพูดได้เกี่ยวกับฟังก์ชั่น (ในการเขียนโปรแกรมเชิงโครงสร้าง) หรือวิธีการ (ในการเขียนโปรแกรมเชิงวัตถุ) และยังเราเห็นฟังก์ชั่น 1K และวัตถุ mega-ass

สิ่งประดิษฐ์ไม่ได้ให้ประโยชน์กับคุณ การใช้สิ่งประดิษฐ์เหล่านั้นอย่างเหมาะสมคือสิ่งที่ให้ประโยชน์เหล่านั้น

การรักษาความปลอดภัย (คุณสามารถให้ / เพิกถอนการอนุญาตในแต่ละ proc ที่เก็บไว้)

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

ปกป้องคุณจากการโจมตีของการฉีด SQL

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

และยังช่วยในเรื่องความเร็วด้วย (แม้ว่า DBA นั้นจะกล่าวว่าเริ่มต้นด้วย SQL Server 2008 แม้กระทั่งคำสั่ง SQL ทั่วไปก็จะถูกคอมไพล์ถ้ามันใช้เวลามากพอ)

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

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

อย่างไรก็ตามสิ่งนี้ไม่ควรเป็นบรรทัดฐาน หากคุณมีหลายกรณีนั่นแสดงว่าเป็นสัญญาณของการออกแบบฐานข้อมูลที่ไม่ดี (หรือคุณดึงข้อมูลจากสกีมาฐานข้อมูลที่เข้ากันไม่ได้ข้ามแผนก)

เรากำลังพัฒนาแอพที่ซับซ้อนโดยใช้วิธีการพัฒนาซอฟต์แวร์ Agile

ความว่องไวเกี่ยวข้องกับกระบวนการวิศวกรรมซอฟต์แวร์และการจัดการความต้องการไม่ใช่เทคโนโลยี

ทุกคนคิดเหตุผลที่ดีว่าทำไมพวกเขาไม่ต้องการใช้ procs ที่เก็บไว้?

คำถามผิด

คำถามนี้ผิดและเทียบเท่ากับการถามว่า "มีเหตุผลอะไรบ้างที่จะไม่ใช้ GOTO" ฉันเข้าข้าง Niklaus Wirth มากกว่า Dijkstra ในเรื่องนี้ ฉันเข้าใจได้ว่าความเชื่อมั่นของ Dijkstra มาจากไหน แต่ฉันไม่เชื่อว่ามันใช้ได้ 100% ในทุกกรณี เหมือนกับ procs ของร้านค้าและเทคโนโลยีใด ๆ

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

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

กล่าวอีกนัยหนึ่งก็คือการคัดออกหรือคำสั่งของความไม่รู้

ฉันเดาว่า DBAs ไม่ต้องการรักษา procs ที่เก็บไว้ แต่ดูเหมือนว่าจะมีวิธีเชิงลบมากเกินไปที่จะพิสูจน์การตัดสินใจในการออกแบบ

สิ่งที่พวกเขากำลังทำคือการฉายผลลัพธ์ของการตัดสินใจทางวิศวกรรมที่ไม่ดีของพวกเขาในเครื่องมือที่พวกเขาใช้ไม่ดี

จะทำอย่างไรในกรณีของคุณ?

ประสบการณ์ของผมคือเมื่ออยู่ในกรุงโรมทำตามที่ชาวโรมันทำ

อย่าสู้กับมัน หากคนใน บริษัท ของคุณต้องการติดป้ายชื่อร้านค้าไว้เป็นแนวทางปฏิบัติที่ไม่ดีให้พวกเขา อย่างไรก็ตามโปรดทราบว่านี่อาจเป็นธงสีแดงในการปฏิบัติด้านวิศวกรรมของพวกเขา

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

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

วิศวกรที่ดีไม่ติดป้ายกำกับว่าเป็นการฝึกฝนที่ไม่ดีในลักษณะทั่วไป พวกเขาดูที่ปัญหาเลือกเครื่องมือที่เหมาะสมทำการแลกเปลี่ยน กล่าวอีกนัยหนึ่งพวกเขาทำวิศวกรรม

ความคิดเห็นของฉันเกี่ยวกับวิธีที่จะไม่ใช้พวกเขา

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

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

  • อย่าทำให้ฐานข้อมูลเป็นที่เดียวที่มีโปรแกรมจัดเก็บของคุณ procs ร้านค้าของคุณควรได้รับการปฏิบัติเช่นเดียวกับที่คุณปฏิบัติกับซอร์สโค้ด C # หรือ Java ของคุณ นั่นคือแหล่งที่มาควบคุมคำนิยามข้อความของ procs ร้านค้าของคุณ ผู้คนพูดจาโผงผางที่ร้านค้าไม่สามารถควบคุมแหล่งที่มาได้ - bullcrap พวกเขาแค่ไม่รู้ว่านรกเลือดพวกเขากำลังพูดถึงอะไร

ความคิดเห็นของฉันในการใช้งานอย่างไร / ที่ไหน

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

  • การควบคุมการเข้าถึงเมล็ดละเอียด คุณไม่ต้องการให้คนโง่ที่เข้าร่วม cartesian ที่ทำงานอยู่ในฐานข้อมูลของคุณ แต่คุณไม่สามารถห้ามคนอื่น ๆ ในการรันคำสั่ง SQL โดยพลการเช่นนั้น วิธีการแก้ปัญหาทั่วไปคือการอนุญาตให้ใช้คำสั่ง SQL โดยพลการในการพัฒนาและสภาพแวดล้อม UAT ในขณะที่ห้ามใช้ในระบบ systest และสภาพแวดล้อมการผลิต คำสั่งใด ๆ ที่จะต้องทำให้มันเป็น systest หรือการผลิตจะเข้าสู่ขั้นตอนการจัดเก็บรหัสตรวจสอบโดยทั้งนักพัฒนาและ dbas

ความต้องการใด ๆ ที่ถูกต้องในการเรียกใช้คำสั่ง SQL ที่ไม่ได้อยู่ใน store proc จะต้องผ่านชื่อผู้ใช้ / บัญชีและกลุ่มการเชื่อมต่ออื่น (ด้วยการใช้งานที่ได้รับการตรวจสอบอย่างเข้มงวดและหมดกำลังใจ)

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

ไม่ว่าคุณจะรันสิ่งนี้บน db เป็น store proc หรือบนเซิร์ฟเวอร์แอปของคุณขึ้นอยู่กับการวิเคราะห์การแลกเปลี่ยนที่คุณต้องทำในฐานะวิศวกร ตัวเลือกทั้งสองจะต้องได้รับการวิเคราะห์และพิสูจน์ด้วยการวิเคราะห์บางประเภท ไม่ทางใดก็ทางหนึ่งโดยกล่าวหาว่าทางเลือกอื่น ๆ ว่า "การปฏิบัติที่ไม่ดี" นั่นเป็นเพียงปัญหาทางวิศวกรรมที่ไม่ดี

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

ไม่ว่าจะเป็นวิธีการแก้ปัญหาอย่างถาวรหรือไม่นั้นเป็นข้อ จำกัด ที่สังเกตได้ในขณะนั้น

หวังว่ามันจะช่วย


14
นี่เป็นคำตอบที่ดีจริงๆ
yfeldblum

5
คำตอบที่ดี แต่นี่ตั้งใจที่จะแดกดัน? "การสรุปเป็นแม่ของสกรูทั้งหมด"
bedwyr

2
ใช่แล้ว ความคิดเห็นของฉันนั้นมีไว้สำหรับประโยคเฉพาะที่อ้างถึงโดย OP ในคำถามดั้งเดิมของเขา ( ขั้นตอนการจัดเก็บไม่ใช่ "วิธีปฏิบัติที่ดีที่สุด" ) คำอธิบายคร่าวๆของขั้นตอนการจัดเก็บเป็นแนวทางปฏิบัติที่ดีที่สุดหรือไม่ดี ไม่สนใจบริบทที่พวกเขาสามารถเป็นคนดีหรือคนเลว (และมักจะนำไปสู่) ทำให้เกิดปัญหาเมื่อทำการสถาปัตย์หรือออกแบบ;)
luis.espinal

7
+1 สำหรับ "การติดฉลากทั่วไปของสิ่งต่าง ๆ เนื่องจากการปฏิบัติที่ไม่ดีมักเกิดขึ้นในองค์กรที่มีโปรแกรมเมอร์ที่ไร้ความสามารถมากมาย" - เคยอยู่ที่นั่นมาตลอดรวมถึงการบอกกับผู้จัดการของฉันว่าเขาคิดว่าฉันมีทางออกที่ยอดเยี่ยมสำหรับปัญหาที่ยุ่งยากอย่างหนึ่ง แต่ถ้าเขาเห็นว่าอนุญาตให้ฉันนำไปใช้มันก็จะเปิดประตูระบายน้ำสำหรับ Muppets
Julia Hayward

1
@Shane คุณพูดถูก อย่างไรก็ตามฉันเชื่อว่าคำตอบนี้พยายามถ่ายทอดคือแนวโน้มของวิศวกรบางกลุ่มที่จะแก้ตัวโดยขาดความรู้หรือการวิเคราะห์โดยการโทรหาบัตรฝึกฝนที่ไม่ดี คำตอบอาจเห็นการปรับปรุงบางอย่างสำหรับเราที่ไม่มีประสบการณ์มากขึ้น
Cesar Hernandez

56

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

(กระบวนงานที่เก็บไว้) ปกป้องคุณจากการโจมตีของการฉีด SQL

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


18
และหาก proc ที่จัดเก็บของคุณกำลังใช้ไดนามิก sql ใด ๆ พร้อมกับพารามิเตอร์สตริงคุณก็จะเริ่มต้นทันที
JeffO

4
ข้อแตกต่างคือสามารถตั้งค่าสิทธิ์การเข้าถึงสำหรับโพรซีเดอร์ที่เก็บตามแต่ละโพรซีเดอร์สำหรับการสืบค้น SQL แบบกำหนดพารามิเตอร์ที่คุณต้องพึ่งพาโปรแกรมเมอร์ที่มีสติไม่ต้องทำ+ "blablabla"เพราะคุณต้องยอมให้ SQL ธรรมดาและที่สิ้นสุดการควบคุม
Coder

19
ฉันไม่เคยเข้าใจ "เชื่อมโยงคุณกับฐานข้อมูลบางอย่าง" โต้แย้ง คุณใช้โปรแกรมของคุณและโยกย้ายไปยังฐานข้อมูลอื่นบ่อยเพียงใด
Mason Wheeler

11
@MasonWheeler - +1 ทุกครั้ง ในโครงการที่มีขนาดใหญ่พอสมควรแอปของคุณจะถูกเขียนลงบนฐานข้อมูลของผลิตภัณฑ์ DB ที่กำหนด การแปลงไปยังฐานข้อมูลอื่นกลายเป็นงานที่สำคัญไม่ว่าจะเกิดอะไรขึ้นเพราะฐานข้อมูลใหม่จะมีความแปลกประหลาดที่แตกต่างกัน!
Michael Kohne

6
@HLGEM - แต่ในโลก COTS จะมี DBs หลายอันในตอนแรก (ตามจริงแล้วคุณเลือก DB ที่เข้ากันได้) ไม่ใช่พอร์ตของคุณ แต่เป็นเพราะคุณรองรับแบ็คเอนด์ที่แตกต่างกันซึ่งเป็นสัตว์ที่แตกต่างไปจากเดิมอย่างสิ้นเชิง
Michael Kohne

46

เหตุผลบางประการที่ฉันเห็นด้วยกับ procs ที่เก็บไว้ไม่ใช่วิธีปฏิบัติที่ดีที่สุด

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

7
คุณสามารถทำการเขียนโปรแกรมทดสอบครั้งแรกในขั้นตอนการจัดเก็บได้ง่ายๆ

5
อืม ... 1) การใช้โพรซีเดอร์ที่เก็บไว้ของฐานข้อมูลนั้นไม่ได้หมายความว่าตรรกะทางธุรกิจจะถูกนำมาใช้ 2) procs ที่เก็บไว้เป็นสิ่งที่ง่ายที่สุดในการทดสอบหน่วย 3) procs ของร้านค้าไม่จำเป็นต้องเป็นสื่อกระแสไฟฟ้าของแนวทางปฏิบัติในการทดสอบครั้งแรกจริง แต่ไม่ใช่ทุกสิ่งที่คำนวณได้สามารถทดสอบได้ก่อน 4) การดีบักไม่ควรเป็นปัญหาเนื่องจาก procs ของร้านค้าไม่ควรมีอะไรมากไปกว่าคำสั่งและเม้าส์ SQL ที่ง่ายต่อการตรวจสอบ นอกจากนี้การดีบักควรดำเนินการโดยการทดสอบและการดีบักคำสั่ง SQL เป็นครั้งแรกจากนั้นย้ายไปที่ procs ของร้านค้า ... เพียงแค่ IMO btw
luis.espinal

6
เห็นได้ชัดว่าคุณไม่ใช่นักพัฒนา DB การควบคุมแหล่งที่มา IDEs - ไอ้การแก้จุดบกพร่อง SP ได้ง่ายถ้าคุณใช้ TOAD หรือ IDE ที่คล้ายกันเหมือนกับการกำหนดเวอร์ชัน
gbjbaanb

6
2) หน่วยทดสอบ procs ที่เก็บไว้ idk เกี่ยวกับเฟรมเวิร์กการทดสอบหน่วยอื่น ๆ แต่อย่างน้อยด้วย MS Test (VisualStudio.TestTools.UnitTesting) การเรียกใช้เมธอด Assert ใด ๆ ใน Proc ที่เก็บไว้อย่างน้อยต้องใช้การเชื่อมต่อ Db ซึ่งโดยนิยามทำให้การทดสอบการรวมเป็นมากกว่าการทดสอบ ทดสอบ. และ proc ที่เก็บไว้อาจอ้างอิงสถานะเกี่ยวกับฐานข้อมูลในระดับฐานข้อมูลระดับโลก สิ่งเหล่านี้อาจไม่สามารถปลอมแปลงหรือมีส่วนต่อประสาน
ต. เว็บสเตอร์

3
+1 นอกจากนี้ภาษาของโพรซีเดอร์ที่เก็บไว้ (pl / sql, t-sql, plpgsql, ฯลฯ ) นั้นมี clunky และ verbose มาก มันง่ายกว่ามากสำหรับฉันที่จะใช้ภาษาสคริปต์เพื่อสร้างการเชื่อมต่อฐานข้อมูลและจัดการตรรกะทางธุรกิจนอกฐานข้อมูล

22

ขั้นตอนการจัดเก็บให้คุณนำรหัสมาใช้ใหม่และการห่อหุ้ม (สองเสาหลักของการพัฒนาซอฟต์แวร์)

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

ปกป้องคุณจากการโจมตีของการฉีด SQL

ไม่พวกเขาทำไม่ได้ ฉันไม่สามารถคาดเดาได้ว่าความคิดนี้อาจมาจากไหนเพราะฉันได้ยินมันพูดบ่อยๆและมันก็ไม่จริง มันอาจช่วยลดการโจมตีของการฉีด SQL บางประเภท แต่ถ้าคุณไม่ได้ใช้การสอบถามแบบพาราเมทริกในตอนแรกนั่นจะไม่สำคัญ I can still '; DROP Table Accounts; -

และยังช่วยในเรื่องความเร็วด้วย (แม้ว่า DBA นั้นจะกล่าวว่าเริ่มต้นด้วย SQL Server 2008 แม้กระทั่งคำสั่ง SQL ทั่วไปก็จะถูกคอมไพล์ถ้ามันใช้เวลามากพอ)

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

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

ฟัง DBA ของคุณ เขารู้ว่าเกิดอะไรขึ้น


1
Red Gate มีผลิตภัณฑ์SQL Source Controlสำหรับ SQL Server แต่ฉันเห็นด้วยการกดตรรกะลงใน procs ที่จัดเก็บเป็นวิธีที่ยอดเยี่ยมเพื่อให้แน่ใจว่าคุณมีตรรกะที่สำคัญไม่อยู่ภายใต้การควบคุมเวอร์ชันใด ๆ
Carson63000

17
@greyfade - "ฉันยังไม่เห็นแหล่งควบคุมสำหรับ SP" - คุณล้อเล่นฉันหรือเปล่า Store proc เป็นเพียงไฟล์ข้อความเลือดที่คุณอัปโหลดในโปรแกรมฐานข้อมูลของคุณ (ซึ่งจะรวบรวมและติดตั้งเพื่อใช้งาน) ทุกที่ที่ฉันทำงานที่เก็บ procs เราเก็บซอร์สโค้ด proc ของร้านค้าไว้ พูด CVS, clearcase หรือ SCM ใดก็ตามที่ใช้งานอยู่ การกล่าวว่า procs ของร้านค้าไม่สามารถควบคุมซอร์สได้ (เพราะอยู่ใน db) ก็เหมือนกับการบอกว่าซอร์สโค้ดของแอปพลิเคชันของฉัน (Java, C # หรืออะไรก็ตาม) ไม่สามารถควบคุมซอร์สได้เพราะถูกรวบรวมและนำไปใช้ในการผลิต
luis.espinal

2
@ luis.espinal: ฉันไม่ได้บอกว่าพวกเขาไม่สามารถอยู่ในการควบคุมแหล่งที่มา ฉันแค่บอกว่าฉันไม่รู้จักเครื่องมือโดยเฉพาะสำหรับการรักษาประวัติของ SPs ซึ่งหมายความว่ารักษาประวัตินั้นไว้ในฐานข้อมูล โปรดอย่าพูดจาโผงผางเพราะฉันเข้าใจผิด
greyfade

1
procs ที่เก็บไว้ของ opur ทั้งหมดอยู่ภายใต้ conrtrol ต้นทางเพียงเพราะว่าคุณเคยเห็น parctices ที่ไม่ดีในอดีตไม่ได้หมายความว่าพวกมันมีอยู่ในการใช้ procs ที่เก็บไว้
HLGEM

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

17

นี่คือสายอย่างเป็นทางการเมื่อฉันทำงานให้กับหนึ่งในห้าใหญ่ไม่กี่ปีหลัง เหตุผลก็คือว่าตั้งแต่ SP จะเชื่อมโยงกับการใช้งานเฉพาะ (PL / SQL เทียบกับ T / SQL เทียบกับ ... ) พวกเขาจึง จำกัด ตัวเลือกเทคโนโลยีโดยไม่จำเป็น

หลังจากอาศัยการโยกย้ายระบบขนาดใหญ่เพียงระบบเดียวจาก T / SQL เป็น PL / SQL ฉันสามารถเข้าใจข้อโต้แย้งได้ ฉันคิดว่ามันเป็นเรื่องตลกเล็กน้อย - มีกี่ที่ที่จะย้ายจากฐานข้อมูลหนึ่งไปยังอีกที่หนึ่งด้วยความตั้งใจ?


10
@DaveE: สำหรับโซลูชันระดับองค์กรคุณอาจพูดถูก หากคุณกำลังสร้างซอฟต์แวร์สำเร็จรูปในทันทีที่คุณจัดส่งบน MSSQL โอกาสที่ยิ่งใหญ่ที่สุดของคุณจะต้องการให้มันรันบน Oracle
Eric J.

3
@Eric: จริงเกินไป ตอนนี้ฉันอยู่ที่ไหนเราใช้ SP จำนวนมากและบอกผู้ใช้ว่า 'ไม่' ถ้าพวกเขาไม่ต้องการ MSSQL ยินดีที่ได้ทำเช่นนั้น
DaveE

3
@DaveE: ทีมขายต้องการให้คุณพูดว่า "ใช่" หรือไม่?
Eric J.

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

@EricJ: ใช่ แต่เมื่อพวกเขาเห็นว่าค่าใช้จ่ายจะทำอะไรกับคอมมิชชันของพวกเขาคำขอจะหายไป
DaveE

17

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

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

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

วิธีจัดการกับข้อผิดพลาด? SQL Server มีข้อผิดพลาดมากมายที่หยุดกระบวนการที่เก็บไว้จากการดำเนินการทันทีและบางอย่างที่บังคับให้มีการตัดการเชื่อมต่อ ตั้งแต่ปี 2005 มีการลอง / จับ แต่ยังมีข้อผิดพลาดจำนวนมากที่ไม่สามารถตรวจจับได้ นอกจากนี้ยังมีสิ่งเดียวกันที่เกิดขึ้นกับการทำสำเนารหัสในการจัดการข้อผิดพลาดและคุณไม่สามารถผ่านข้อยกเว้นได้อย่างง่ายดายหรือทำให้เกิดฟองขึ้นในระดับที่สูงขึ้นเช่นเดียวกับภาษาโปรแกรมส่วนใหญ่ .....

ความเร็วก็เช่นกัน การดำเนินการกับชุดข้อมูลจำนวนมากไม่ใช่ชุดข้อมูล หากคุณพยายามทำสิ่งต่าง ๆ ที่เกี่ยวกับแถวไม่ว่าคุณจะใช้เคอร์เซอร์หรือคุณจะใช้ "เคอร์เซอร์" (เมื่อนักพัฒนามักจะสืบค้นแต่ละแถวทีละรายการและเก็บเนื้อหาไว้ในตัวแปร @ เช่นเดียวกับเคอร์เซอร์ .. ถึงแม้ว่านี่จะช้ากว่าเคอร์เซอร์ FORWARD_ONLY) ด้วย SQL Server 2000 ฉันมีบางอย่างที่ทำงานเป็นเวลา 1 ชั่วโมงก่อนที่ฉันจะฆ่ามัน ฉันเขียนโค้ดนั้นอีกครั้งใน Perl แล้วเสร็จใน 20 นาที เมื่อภาษาการเขียนสคริปต์ที่ช้ากว่า C ถึง 20-80x จะทำให้ SQL มีประสิทธิภาพคุณไม่จำเป็นต้องเขียนการดำเนินงานของแถวใน SQL

ตอนนี้ SQL Server จะมีการรวม CLR และปัญหาเหล่านี้หายไปมากถ้าคุณใช้ขั้นตอนการเก็บ CLR แต่ DBA จำนวนมากไม่ทราบวิธีการเขียนโปรแกรม. NET หรือปิด CLR เนื่องจากข้อกังวลด้านความปลอดภัยและติดกับ Transact SQL .... นอกจากนี้ยังมี CLRs คุณยังคงมีปัญหาในการแบ่งปันข้อมูลระหว่างกระบวนการหลายวิธีอย่างมีประสิทธิภาพ .

โดยทั่วไปสิ่งที่ยากที่สุดในการขยายออกคือฐานข้อมูล หากตรรกะทางธุรกิจทั้งหมดของคุณอยู่ในฐานข้อมูลจากนั้นเมื่อฐานข้อมูลช้าเกินไปคุณจะมีปัญหา หากคุณมีเลเยอร์ธุรกิจคุณสามารถเพิ่มแคชและเซิร์ฟเวอร์ธุรกิจได้มากขึ้นเพื่อเพิ่มประสิทธิภาพ ตามเนื้อผ้าเซิร์ฟเวอร์อื่นเพื่อติดตั้ง windows / linux และเรียกใช้. NET / Java นั้นถูกกว่าการซื้อเซิร์ฟเวอร์ฐานข้อมูลอื่นและออกใบอนุญาต SQL Server ให้มากขึ้น SQL Server มีการสนับสนุนการทำคลัสเตอร์มากขึ้นในตอนนี้ แต่เดิมมันไม่ได้มีจริงๆ ดังนั้นหากคุณมีเงินจำนวนมากคุณสามารถเพิ่มการจัดกลุ่มหรือแม้กระทั่งการจัดส่งบันทึกบางส่วนเพื่อทำสำเนาอ่านอย่างเดียวหลาย ๆ แต่โดยรวมแล้วสิ่งนี้จะมีค่าใช้จ่ายมากกว่าแค่การเขียนแคชหรืออะไรบางอย่าง

ดูที่สิ่งอำนวยความสะดวก Transact-SQL การจัดการสตริง? ฉันจะเรียน Java String Class / Tokenizer / Scanner / Regex ทุกวัน ตารางแฮช / รายการที่เชื่อมโยง / อื่น ๆ ฉันจะใช้กรอบการทำงานของคอลเลกชัน Java ฯลฯ ... และเหมือนกันสำหรับ. NET ... ทั้ง C # และ Java เป็นวิธีการพัฒนาภาษามากกว่า Transact SQL ... การเข้ารหัส Heck ด้วย Transact-SQL ทำให้ฉันอิจฉา C .. .

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

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

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

โดยรวมแล้วฉันคิดว่า SQL และ Transact SQL เป็นภาษาที่ยอดเยี่ยมสำหรับการสืบค้น / อัปเดตข้อมูล แต่สำหรับการเข้ารหัสลอจิกประเภทใด ๆ ให้ทำการจัดการสตริง (หรือจัดการไฟล์ heck .... คุณจะประหลาดใจกับสิ่งที่คุณสามารถทำได้กับ xp_cmdshell .... ) ได้โปรดอย่า ฉันหวังว่าจะหาสถานที่ในอนาคตที่ไม่ได้ใช้วิธีการที่เก็บไว้เป็นส่วนใหญ่ จากมุมมองการบำรุงรักษารหัสพวกเขาเป็นฝันร้าย นอกจากนี้จะเกิดอะไรขึ้นถ้าคุณต้องการเปลี่ยนแพลตฟอร์ม (แม้ว่าจริงๆแล้วถ้าคุณชำระเงินสำหรับเซิร์ฟเวอร์ Oracle / DB2 / Sybase / Sql / etc) คุณอาจได้รับทุกสิ่งที่คุณสามารถทำได้โดยใช้ส่วนขยายที่เป็นกรรมสิทธิ์ซึ่งคุณสามารถช่วยคุณได้ .. )

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


6
แต่ฉันก็อดไม่ได้ที่จะเสนออาหารสำหรับความคิดเกี่ยวกับประเด็นเชิงเปรียบเทียบกับขั้นตอนทั้งหมด ฉันได้เห็นเคอร์เซอร์ฐานข้อมูลที่ใช้ในทุกกรณีที่วิธีการนั้นเป็นเพียงถั่ว ฉันได้แทนที่ SQL ที่อิงกับเคอร์เซอร์อย่างชัดเจน (Oracle PL / SQL ในกรณีนั้น) ด้วยชุดการสืบค้นที่มุ่งเน้นและเห็นผลลัพธ์กลับมาภายในไม่กี่วินาทีแทนที่จะเป็น 8 นาที ฉันใช้เวลา 30 นาทีในการตัดรหัสเคอร์เซอร์ 1,000 บรรทัดแล้ว "รับ" แบบสอบถาม SQL ที่ได้นั้นมีความกระชับสวยงามและเรียบง่าย ผู้คนดูถูกพลังของเซิร์ฟเวอร์ฐานข้อมูลบ่อยเกินไปและเร็วเกินไป
Craig

12

คุณทำเวอร์ชันโพรซีเดอร์ที่เก็บไว้บนเซิร์ฟเวอร์อย่างไร?

ถ้าคุณปรับใช้กระบวนงานที่เก็บไว้กับเซิร์ฟเวอร์จากการควบคุมเวอร์ชันใหม่คุณจะระเบิดแผนการดำเนินการที่เก็บไว้

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

ในขณะที่กระบวนงานที่เก็บไว้ไม่สามารถเคลื่อนย้ายได้ แต่ SQL โดยทั่วไปก็ไม่เคยมี (ไม่เคยเห็น oracle date date handling - uggghhh)

ดังนั้นหากคุณต้องการความสะดวกในการพกพาให้สร้าง API การเข้าถึงข้อมูลภายใน คุณสามารถเรียกสิ่งนี้เช่นการเรียกใช้ฟังก์ชั่นและภายในคุณสามารถสร้างในศัพท์แสงใด ๆ ที่คุณต้องการด้วยแบบสอบถามแบบกำหนดพารามิเตอร์และสามารถควบคุมเวอร์ชันได้


6
คุณทำเวอร์ชันโพรซีเดอร์ที่เก็บไว้บนเซิร์ฟเวอร์ได้อย่างไร? - เวอร์ชั่นของคุณควบคุม source code ของ store proc เมื่อถึงเวลาที่จะต้องปรับใช้คุณจะคว้า Store procs (จาก baseline ที่กำหนด) และคุณ (หรือ dba ของคุณ) ปรับใช้กับการผลิต การปรับใช้ใหม่ (ไม่ว่าจะเป็นการทดสอบหรือการผลิต) จะทำให้แผนบริหารจัดการที่เก็บไว้ออกมาระเบิดอย่างแน่นอน
luis.espinal

1
@BarryBrown มันไม่ทำงานถ้าคนมีการเข้าถึงเซิร์ฟเวอร์โดยตรงและสามารถเปลี่ยนขั้นตอนการจัดเก็บ ฉันจะต้องมีกระบวนการที่นาฬิกาสำนักหรือมีการตรวจสอบก่อนการใช้งานแต่ละ ...
คริสฮัน

2
หากคุณมีคนกำลังเปลี่ยน sprocs จำใจบนเซิร์ฟเวอร์โดยไม่ทำการเปลี่ยนแปลงการควบคุมแหล่งที่มาคุณมีปัญหากระบวนการที่เกือบจะแน่นอนส่งผลกระทบต่อการพัฒนารหัสจำเป็นของคุณเช่นกันแม้ว่าคุณจะไม่ทราบว่ามันเป็น
Craig

1
หนึ่งในสิ่งที่ฉันทำในอดีตคือการวางอินสแตนซ์การพัฒนาของเซิร์ฟเวอร์ฐานข้อมูลบนเวิร์กสเตชันของผู้พัฒนารายบุคคลหรือถ้าเป็นไปไม่ได้อย่างน้อยก็มีอินสแตนซ์ "dev" และ "การผลิต" ของฐานข้อมูล และสคริปต์ DDL และ DML ทั้งหมดรวมถึงข้อมูลตัวอย่างและสคริปต์โหลดที่อยู่ภายใต้ไดเรกทอรีของตัวเองในแผนผังแหล่งที่มาและฐานข้อมูลถูกสร้างขึ้นเป็นประจำจากสคริปต์เหล่านั้นโดยใช้ไฟล์ MAKE ผู้พัฒนาสามารถใช้ nmake เพื่อสร้าง procs ที่จัดเก็บเดี่ยวได้เช่นกัน หากพวกเขาไม่ได้อยู่ภายใต้การควบคุมของแหล่งข้อมูลมันจะหายไปกับพวกเขาและพวกเขาก็รู้
Craig

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

9

ตรงกันข้ามกับทุกสิ่งที่ฉันเรียนรู้

คุณอาจต้องออกไปมากขึ้น [ยิ้ม] procs ที่จัดเก็บอย่างจริงจังได้ลดลงอย่างน้อย 10 ปี ค่อนข้างมากตั้งแต่ n-tier มาแทนที่ไคลเอ็นต์ - เซิร์ฟเวอร์ การลดลงนั้นเกิดขึ้นจากการใช้ภาษา OO เช่น Java, C #, Python เป็นต้น

นั่นไม่ใช่การบอกว่า procs ที่เก็บไว้ยังไม่มีผู้สนับสนุนและผู้สนับสนุน แต่นี่เป็นการอภิปรายและการอภิปรายที่ยาวนาน มันไม่ใช่เรื่องใหม่และมีแนวโน้มที่จะเกิดขึ้นอีกระยะหนึ่ง IMO ฝ่ายตรงข้ามของ procs ที่เก็บไว้ชนะอย่างชัดเจน

ขั้นตอนการจัดเก็บจะช่วยให้คุณสามารถนำโค้ดกลับมาใช้ใหม่และห่อหุ้ม (สองเสาหลักของการพัฒนาซอฟต์แวร์)

จริงแท้แน่นอน. แต่ชั้น OO ที่ได้รับการออกแบบมาอย่างเหมาะสม

การรักษาความปลอดภัย (คุณสามารถให้ / เพิกถอนสิทธิ์ใน proc ที่จัดเก็บแต่ละรายการ)

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

ปกป้องคุณจากการโจมตีของการฉีด SQL

ไม่มากไปกว่าการทำแบบสอบถามแบบมีพารามิเตอร์ ซึ่งคุณต้องทำต่อไป

และยังช่วยในเรื่องความเร็วด้วย (แม้ว่า DBA นั้นจะกล่าวว่าเริ่มต้นด้วย SQL Server 2008 แม้กระทั่งคำสั่ง SQL ทั่วไปก็จะถูกคอมไพล์ถ้ามันใช้เวลามากพอ)

ฉันคิดว่าเริ่มต้นใน MSSQL 7 หรือ 2000 มีการถกเถียงการวัดและการใช้ข้อมูลที่ผิดในการทำงานของ proc vs inline SQL มากมาย - ฉันพบปัญหาทั้งหมดภายใต้ YAGNI และถ้าคุณต้องการทดสอบ

เรากำลังพัฒนาแอพที่ซับซ้อนโดยใช้วิธีการพัฒนาซอฟต์แวร์ Agile ทุกคนคิดเหตุผลที่ดีว่าทำไมพวกเขาไม่ต้องการใช้ procs ที่เก็บไว้?

ฉันไม่สามารถคิดในหลายเหตุผลที่คุณจะต้องการที่จะ Java / C # / ภาษา GL ที่ 3 ใด ๆ นั้นมีความสามารถมากกว่า T-SQL ในการห่อหุ้ม, นำมาใช้ใหม่และ felxibility เป็นต้นซึ่งส่วนใหญ่นั้นฟรี ORM ที่มีค่าครึ่งเดียว

นอกจากนี้ยังได้รับคำแนะนำในการ "แจกจ่ายตามที่ต้องการ แต่ไม่เกิน" - ฉันคิดว่าภาระการพิสูจน์ในทุกวันนี้อยู่ที่ผู้สนับสนุนของ SP สาเหตุทั่วไปของการเก็บ proc ที่หนักก็คือ T-SQL นั้นง่ายกว่า OO และร้านค้านั้นมี T-SQL devs ที่ดีกว่า OO หรือที่ DBA หยุดที่เลเยอร์ฐานข้อมูลและ procs ที่เก็บไว้เป็นส่วนต่อประสานระหว่าง dev และ DBA หรือคุณกำลังจัดส่งผลิตภัณฑ์แบบกึ่งกำหนดเองและ procs ที่จัดเก็บสามารถกำหนดเองได้ ขาดการพิจารณาบางอย่างเช่นนั้นฉันคิดว่าค่าเริ่มต้นสำหรับโปรเจ็กต์ Agile SW ทุกวันนี้จะเป็น ORM


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

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

1
อย่าประมาทเซิร์ฟเวอร์ฐานข้อมูลของคุณ เรียนรู้วิธีการใช้อย่างถูกต้อง
Craig

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

1
จริงทั้งหมดและฉันก็เถียงกับ SQL มากกว่าการโต้เถียงโดยเฉพาะสำหรับ sprocs แต่การมี SQL ที่ฝังอยู่ในโค้ดที่จำเป็นของคุณไม่จำเป็นต้องเป็นกุญแจสู่ความสุขใช่ไหม? ซึ่งมักนำไปสู่การอภิปราย ORM ทั้งหมดซึ่งทำให้ฉันชี้ไปที่การเปรียบเทียบประสิทธิภาพระหว่างการเข้าถึงฐานข้อมูล ORM ที่ควบคุมด้วย ORM เทียบกับการเรียนรู้วิธีใช้ SQL ฉันได้ทั้งเห็นและได้ยินเสียงของระบบต่าง ๆ ที่กล่าวว่าที่ปรึกษาของออราเคิลแนะนำการรักษาทั้งหมดโหลดไปได้ปิดเซิร์ฟเวอร์ฐานข้อมูลที่นำไปสู่หนัก (และแพงอย่างไม่มีการลด!) มิดเดิลแวร์กับสุดซึ้งประสิทธิภาพ
Craig

4

เมื่อพิจารณาจากกรณีทั้งหมดข้างต้นฉันต้องการเพิ่มอีกหนึ่งรายการ ทางเลือกของ SP อาจขึ้นอยู่กับการเลือกของผู้คนด้วย

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

SP ควรใช้สำหรับการดำเนินการอย่างง่ายเท่านั้น นั่นคือทางเลือกของฉัน


4

ฉันต้องการครอบคลุมทั้งปัญหาและปัญหาของโปรแกรมที่จัดเก็บไว้ เราใช้มันอย่างกว้างขวางด้วยLedgerSMBและกฎของเราคือด้วยส่วนขยายที่เฉพาะเจาะจงน้อยมาก "ถ้าเป็นแบบสอบถามให้เป็น proc ที่เก็บไว้"

เหตุผลของเราในการทำเช่นนี้คือเพื่อช่วยนำการค้นหาข้ามภาษามาใช้ซ้ำ ไม่มีวิธีที่ดีกว่าในการทำสิ่งนี้โดยสุจริต

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

ดังนั้นไปยังด้านแย้ง

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

  2. ใช่เป็นไปได้ที่จะมีการฉีด sql ภายในถ้าทำแบบไดนามิกใด ๆ sql มันเป็นสิ่งที่ไม่ดีที่จะมีความมั่นใจมากเกินไปในพื้นที่นี้และดังนั้นจึงจำเป็นต้องมีประสบการณ์ที่สำคัญในด้านความปลอดภัยในพื้นที่นี้

  3. การเปลี่ยนแปลงอินเทอร์เฟซนั้นค่อนข้างมีปัญหากับขั้นตอนการจัดเก็บด้วยเหตุผล # 1 ข้างต้น แต่นี่อาจกลายเป็นฝันร้ายที่ยิ่งใหญ่หากแอพไคลเอนต์จำนวนมากเข้ามาเกี่ยวข้อง

ข้างต้นค่อนข้างยากที่จะปฏิเสธ พวกเขาเกิดขึ้น ทุกคนโปร SP และแอนตี้เอสพีอาจมีเรื่องราวสยองขวัญเกี่ยวกับสิ่งเหล่านี้ ปัญหาไม่สามารถแก้ไขได้ แต่ถ้าคุณไม่ใส่ใจพวกเขาคุณไม่สามารถแก้ปัญหาเหล่านั้นได้ (ใน LedgerSMB เราใช้ตัวระบุบริการเพื่อสร้างการโทรแบบ SP ในเวลาทำงานหลีกเลี่ยงปัญหาข้างต้นทั้งหมดในขณะที่เรา PostgreSQL เท่านั้นสิ่งที่คล้ายกันสามารถทำได้สำหรับ db อื่น ๆ )

เมื่อวันที่บวก สมมติว่าคุณสามารถแก้ปัญหาข้างต้นคุณจะได้รับ:

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

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

  3. ข้อความค้นหาใช้ซ้ำ

โอ้และบางสิ่งที่คุณไม่ควรทำใน SP:

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

  2. มีการค้นหาจำนวนเล็กน้อยที่คลึงกันหลวม ๆ โรยด้วยตรรกะเชิงกระบวนงาน ....


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

3

คุณทำงานเพื่อใคร?

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

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

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

ป้อนคำอธิบายรูปภาพที่นี่

สำหรับ (จำนวนมาก) การอภิปรายทั้งสองด้านของรั้วอ่านการอภิปรายที่เข้ารหัสสยองขวัญ FWIW ฉันเอนตัวไปด้านข้างของผู้สนับสนุน SP


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

นอกจากนี้คุณเชื่อมโยงบทความตั้งแต่ปี 2004 IMHO ภูมิทัศน์เปลี่ยนไปเล็กน้อยตั้งแต่นั้นมา OR / M กลายเป็นเรื่องธรรมดาไปแล้ว Ruby / Rails ActiveRecord, MS ออกมาพร้อม linq & EF, Django สำหรับ python และอื่น ๆ
Brook

@Justice เขาพูดถูกแต่ทว่าการปฏิบัติที่ดีที่สุดของ storageprocs นั้นขึ้นอยู่กับว่า บริษัท เป็นใครและมีบทบาทอย่างไร ตัวอย่างเช่น procs ที่เก็บไว้อนุญาตให้คุณตั้งค่าการอนุญาตใน proc เองและไม่ได้อยู่บนโต๊ะโดยตรง หากคุณกำลังทำงานด้านการเงินและต้องพิจารณาการควบคุมภายในพวกเขาเป็นทางเลือกเดียวที่ทำงานได้สำหรับการปกป้องข้อมูลของคุณจากผู้ใช้ แต่ถ้าคุณกำลังสร้างผลิตภัณฑ์ COTS ที่มีแบ็กเอนด์ที่เป็นไปได้หลายรายการมันเป็นฐานข้อมูลที่เฉพาะเจาะจงเกินไป หากคุณเป็น บริษัท ที่ปรึกษาคุณอาจต้องพิจารณาแนวทางที่แตกต่างกันหลายวิธีที่ดีที่สุดสำหรับสถานการณ์
HLGEM

3
@HLGEM ฉันไม่คัดค้านต่อประเด็นที่คุณแจ้งมา แต่ฉันไม่เห็นด้วยกับคำตอบของวิทยานิพนธ์ว่าสาเหตุหลักที่ DBA อาจใส่ตรรกะลงในใบสมัครเป็นเพราะเขาเป็นที่ปรึกษาและตั้งใจที่จะทำให้ลูกค้าเข้าใจผิด มันเชื่อมโยงจุดยืนทางศีลธรรมของบุคคลกับการเลือกว่าจะใช้วิธีการที่เก็บไว้หรือไม่ ในความคิดของฉันมีข้อโต้แย้งทางเทคนิคทั้งสองด้านและข้อโต้แย้งของทั้งสองฝ่ายจะแตกต่างจากแอปพลิเคชันแอปพลิเคชันเทคโนโลยีเทคโนโลยี บริษัท บริษัท บริษัท อุตสาหกรรมอุตสาหกรรม และฉันจะมองหาบุญก่อนที่จะกระตุ้นแรงจูงใจ
yfeldblum

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

3

มันยากมากที่จะเปลี่ยนแบรนด์ฐานข้อมูลและใช้วิธีการจัดเก็บแบบเดิม

ทีมของคุณไม่มี DBA และไม่มีใครต้องการมีส่วนร่วมกับ sql

นี่คือไม่มีอะไรมากไปกว่าการประกวดเขียนโปรแกรม v DBA pissing


2

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


Downvoters จะแสดงความคิดเห็น
SandRock

2

เป็นแหล่งที่มาของปัญหาเสมอในการแยกตรรกะทางธุรกิจระหว่างเลเยอร์ต่างๆโดยใช้ภาษาการเขียนโปรแกรมที่แตกต่างกัน การติดตามบั๊กหรือการใช้การเปลี่ยนแปลงเป็นเรื่องยากเมื่อคุณต้องสลับระหว่างโลก

ที่กล่าวว่าฉันรู้ว่า บริษัท ที่ทำได้ค่อนข้างดีโดยวางตรรกะทางธุรกิจทั้งหมดลงในแพ็คเกจ PL / SQL ที่อาศัยอยู่ในฐานข้อมูล สิ่งเหล่านี้ไม่ใช่แอปพลิเคชันที่มีขนาดใหญ่มาก แต่ก็ไม่สำคัญ พูด 20K-100K LOC (PL / SQL เหมาะกว่าสำหรับระบบประเภทนั้นดีกว่า T-SQL ดังนั้นหากคุณรู้จัก T-SQL เพียงอย่างเดียวคุณอาจสลัดหัวของคุณในตอนนี้ ...


2

นี่เป็นอีกประเด็นที่ยังไม่ได้กล่าวถึง:

เครื่องมือสร้างรหัสและเครื่องมือวิศวกรรมย้อนกลับไม่สามารถรับมือกับกระบวนการจัดเก็บได้ เครื่องมือโดยทั่วไปไม่สามารถบอกได้ว่า proc ทำอะไร proc ส่งคืน resultset หรือไม่? มีหลาย resultsets? มันดึงเอา resultsets จากหลาย ๆ ตารางและตารางชั่วคราวหรือไม่? proc เป็นเพียงคำสั่งการอัพเดตที่ถูกห่อหุ้มและไม่ส่งคืนอะไร? มันส่งคืนชุดผลลัพธ์, ค่าส่งคืนและ "คอนโซลเอาต์พุต" บางส่วนหรือไม่?

ดังนั้นหากคุณต้องการใช้เครื่องมือในการสร้าง data-transfer-object DTO และ DAO layer โดยอัตโนมัติ (เช่น "service builder" ของ liferay) คุณจะไม่สามารถทำได้อย่างง่ายดาย

ยิ่งไปกว่านั้น ORMs เช่น Hibernate ไม่สามารถทำงานได้อย่างถูกต้องเมื่อแหล่งข้อมูลเป็น SP การเข้าถึงข้อมูลเป็นแบบอ่านอย่างเดียวที่ดีที่สุด


เป็นที่น่าสนใจว่าเครื่องมือในการสร้างรหัสมีช่วงเวลาที่ยากลำบากในการพิจารณาว่าโพรซีเดอร์ที่เก็บไว้ส่งคืนชุดผลลัพธ์หรือไม่เมื่อโพรซีเดอร์ที่เก็บไว้เองไม่มีปัญหาใด ๆ
Craig

2

การเขียนโปรแกรมเดี่ยวฉันไม่สามารถต้านทานขั้นตอนการเขียนที่เก็บไว้ได้

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

logInดังนั้นฉันจึงมีขั้นตอนที่เรียกว่า เมื่อคุณเข้าสู่ระบบคุณก็เพียงแค่ผ่านและusername ผลที่ได้ส่งกลับเป็นจำนวนเต็มpassworduserId

เมื่อlogInเป็นขั้นตอนที่เก็บไว้ตอนนี้ฉันสามารถเพิ่มการทำงานเพิ่มเติมที่จะต้องทำในการเข้าสู่ระบบที่เกิดขึ้นในเวลาเดียวกันกับการเข้าสู่ระบบในเบื้องต้น. ฉันพบชุดของคำสั่ง SQL กับตรรกะที่ฝังอยู่ในขั้นตอนการเก็บง่ายต่อการเขียนกว่า (เรียก environment FETCH) -> (รับผล) -> (เรียก FETCH environment environment) ซีรีส์ที่คุณต้องทำเมื่อคุณเขียนด้านลอจิกเซิร์ฟเวอร์


1

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


3
เป็นการยากที่จะขยายฐานข้อมูลหรือไม่
JeffO

1
มันเป็นอย่างน้อยอย่างมีนัยสำคัญราคาแพงมากขึ้น (ยกเว้นกรณีของคุณบน MySQL) และในหลาย ๆ สถานที่ที่ผมเคยทำงานที่ได้รับใบอนุญาตอีก SQL Server Enterprise Edition เป็นเหมือนการดึงฟัน
เบนฉ

ฐานข้อมูลการปรับสเกลนั้นไม่ยากไปกว่าการขยายส่วนท้ายของเลเยอร์แอป
Brian Ogden

1

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

ที่กล่าวว่าเรากำลังใช้ SP ในโครงการปัจจุบันของฉัน เหตุผลก็เพราะเรากำลังสร้างแอปพลิเคชั่นใหม่บนฐานข้อมูลที่มีอยู่ซึ่งยังคงรองรับแอปพลิเคชันรุ่นเก่า ด้วยเหตุนี้การเปลี่ยนแปลงสคีมาจึงเป็นเรื่องยากมากจนกระทั่งเราปิดแอปดั้งเดิม เราตัดสินใจอย่างมีสติในการออกแบบแอปพลิเคชันใหม่ของเราตามพฤติกรรมและกฎระเบียบที่จำเป็นสำหรับแอปพลิเคชันและใช้ SP เพื่อเชื่อมต่อกับฐานข้อมูลชั่วคราวในแบบที่เราต้องการให้เป็นและอนุญาตให้ SPs ปรับให้เข้ากับ SQL ที่มีอยู่ . สิ่งนี้จะไปที่จุดโปสเตอร์ก่อนหน้านี้ที่ SP ทำให้การเปลี่ยนแปลงในระดับฐานข้อมูลง่ายขึ้นโดยไม่ต้องทำการเปลี่ยนแปลงรหัสแอปพลิเคชัน การใช้ SP เป็นการนำรูปแบบของอะแด็ปเตอร์มาใช้อย่างเหมาะสม (โดยเฉพาะในโครงการปัจจุบันของฉัน)

Fwiw เป็นความตั้งใจของเราที่จะลบ SP เมื่อสกีมาอัพเดท แต่เช่นเดียวกับทุกอย่างในการพัฒนาองค์กรเราจะดูว่ามันเกิดขึ้นจริงหรือไม่! [ยิ้ม]


0

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

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

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

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


-1

ขั้นตอนการจัดเก็บ "สำหรับฉัน" เหมาะสำหรับการดำเนินการ "อ่านอย่างเดียว" ของ OLAP ซึ่งเป็นการใช้งานที่หายาก

สำหรับกฎทางธุรกิจการดำเนินการอ่าน / เขียน OLTP ฉันชอบเซิร์ฟเวอร์แอปพลิเคชัน Java เพื่อความสะดวกในการเข้ารหัสและลดการโหลด cpu และหน่วยความจำให้มากที่สุดจากเซิร์ฟเวอร์ master db ในการตั้งค่ารหัสทั้งหมดในเซิร์ฟเวอร์แอปพลิเคชันนั้นไม่ยากที่จะตรวจสอบหรือบันทึกและปรับขนาดได้

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


คุณได้ตั้งสมมติฐานบางอย่าง: OP มีความต้องการ OLAP (ไม่ได้ระบุไว้ในคำถาม); ที่แพลตฟอร์มที่ใช้มีเซิร์ฟเวอร์แอปพลิเคชัน Java (ไม่น่าเป็นไปได้เนื่องจากแท็กเกี่ยวกับ SQL Server) คำตอบของคุณไม่ได้นำมาซึ่งอะไรอีก 22 คำตอบที่ไม่ได้ครอบคลุม
Adam Zuckerman

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

สิ่งนี้ดูเหมือนจะไม่นำเสนอสิ่งใดเกินกว่าที่ทำและอธิบายไว้ใน 24 คำตอบก่อนหน้านี้แทบจะไม่มีเนื้อหาที่น่าสนใจสำหรับคำถามอายุ 4 ปี
gnat

-2

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

เลือกเครื่องมือของคุณอย่างชาญฉลาดและคุณจะช่วยตัวเองให้รอดพ้นจากความเจ็บปวดในระยะยาว


หากคุณกำลังจะลงคะแนนให้ทำเช่นนั้น แต่อย่างน้อยก็อธิบายว่าทำไม
Nico

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

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