สำหรับการตรวจสอบความถูกต้องของข้อมูลสนับสนุน ORM ควรมีการบังคับใช้ข้อ จำกัด ในฐานข้อมูลด้วยหรือไม่


13

ฉันมักใช้ข้อ จำกัด ในระดับฐานข้อมูลเพิ่มเติมจากรุ่น (ActiveRecord) ของฉัน แต่ฉันสงสัยว่าสิ่งนี้จำเป็นจริงๆหรือ?

พื้นหลังเล็กน้อย

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

ข้อได้เปรียบที่เป็นไปได้ถ้าฉันข้ามข้อ จำกัด ใน db, imo -

  • สามารถแก้ไขกฎการตรวจสอบในรูปแบบโดยไม่ต้องย้ายฐานข้อมูล
  • สามารถข้ามการตรวจสอบในการทดสอบ

ข้อเสียที่เป็นไปได้?

หากเป็นไปได้ว่าการตรวจสอบความถูกต้องของ ORM ล้มเหลวหรือถูกข้ามไปฐานข้อมูลจะไม่ตรวจสอบข้อ จำกัด

คุณคิดอย่างไร?

แก้ไขในกรณีนี้ฉันใช้Yii Frameworkซึ่งสร้างแบบจำลองจากฐานข้อมูลดังนั้นกฎฐานข้อมูลจึงถูกสร้างขึ้นด้วย


3
หากข้อมูลในฐานข้อมูลของคุณสามารถแก้ไขเป็นประจำได้โดยไม่ต้องใช้ ORM ของคุณ (แอปอื่น ๆ ที่ไม่มี ORM ของคุณหรือแย่กว่านั้นคือการเข้าถึงฐานข้อมูลโดยตรงจากผู้ใช้) การตรวจสอบจะต้องอยู่ในฐานข้อมูล
Marjan Venema

คำตอบ:


16

หลักการชี้นำของคุณไม่ควรซ้ำไปซ้ำมา :

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

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

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

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

ความล้มเหลว

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

ข้าม ORM เพื่อสิ่งอื่น

ยังไม่ใช่ความคิดที่ดี อย่างไรก็ตามอาจเกิดขึ้นได้จากหลายสาเหตุ:

  1. ส่วนดั้งเดิมของแอปพลิเคชันที่สร้างขึ้นก่อนที่ ORM จะได้รับการแนะนำ

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

    ลองเปลี่ยนกุญแจในตาราง MySQL ขนาด 2 * 10 ^ 8 ที่ออกแบบมาไม่ดี (โดยไม่ต้องหยุดทำงาน) และคุณจะเข้าใจว่าฉันมาจากไหน

  2. ส่วนที่ไม่ใช่มรดกของแอปพลิเคชันที่จำเป็นต้องพูดคุยกับที่จัดเก็บข้อมูลโดยตรง:

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

ความคิดเห็น

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

นี่คือที่เพิ่มเลเยอร์พิเศษจะเป็นประโยชน์อย่างยิ่งและถ้าเรากำลังพูดถึงเว็บแอปพลิเคชันฉันจะไปกับ REST API การออกแบบที่ง่ายเกินไปสำหรับสิ่งนี้จะเป็น:

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

ORM จะอยู่ระหว่าง API กับแหล่งเก็บข้อมูลและทุกอย่างที่อยู่เบื้องหลัง API (รวมถึง) จะถือว่าเป็นเอนทิตีเดียวจากแอปพลิเคชันต่างๆ


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

2
@JoshK คุณพูดถึงระดับที่สองของความมั่นใจฉันพูดว่าการบำรุงรักษานรก ไม่ได้บอกว่าคุณพูดถูก แต่ ...
ยานนิส

มีเหตุผล. ฉันกำลังติดตามเส้นทางนี้ตอนนี้ ขอบคุณ!
na

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

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

20

จริงๆแล้วนี่เป็นคำถามที่ตอบยากมากและฉันพบว่ามันเป็นเรื่องที่ถกเถียงกันมาก

ดังที่ Yannis Rizos ชี้ให้เห็นในคำตอบของเขาการมีเหตุผลที่ จำกัดทั้งในฐานข้อมูลและเลเยอร์ ORMดูเหมือนจะเป็นการละเมิด DRY ซึ่ง "สามารถนำไปสู่การบำรุงรักษาฝันร้ายการแยกตัวประกอบและตรรกะที่ขัดแย้งกัน"

อย่างไรก็ตามการลบตรรกะข้อ จำกัด ออกจากฐานข้อมูลและเก็บไว้ที่เลเยอร์ ORM เท่านั้นจะไม่ทำงานหากคุณมีเงื่อนไขใด ๆ ต่อไปนี้:

  1. อัพเดตฐานข้อมูลด้วยตนเอง (ดูเหมือนว่าจะเกิดขึ้นในทุก บริษัท )

  2. การอัพเดตฐานข้อมูลจากระบบอื่นที่ไม่สามารถแชร์ตรรกะข้อ จำกัด ORM ได้อย่างง่ายดาย (ex / a Perl script ที่ทำงานประจำเมื่อเลเยอร์ ORM ถูกนำมาใช้ในไฮเบอร์เนตและใช้โดยแอปพลิเคชัน Java สำหรับกิจกรรมวันต่อวัน)

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

ตัวเลือกสุดท้ายของคุณคือการสร้างข้อ จำกัด โดยอัตโนมัติใน ORM (และระบบอื่น ๆ ) จากข้อ จำกัด ของฐานข้อมูล (หรือจริง ๆ ... ในทางกลับกัน) แม้ว่าในที่สุดคุณจะจบลงด้วยการบังคับใช้ข้อ จำกัด สองข้อขึ้นไป แต่จะไม่เป็นการละเมิดหลักการ DRY ดังที่อธิบายไว้ใน "The Pragmatic Programmer" เนื่องจากพวกเขาแนะนำให้ใช้การสร้างรหัสเพื่อหลีกเลี่ยงการละเมิด DRY แน่นอนว่าไม่ใช่เรื่องง่ายเพราะตัวอย่างเช่นการเปลี่ยนแปลงทุกข้อ จำกัด ของฐานข้อมูลอาจบังคับให้สร้างใหม่และปรับใช้แอปพลิเคชันทั้งหมดของคุณที่ใช้งานใหม่ (ไม่ใช่เรื่องง่ายที่จะทำให้เป็นอัตโนมัติ)

จริงๆแล้วมันจะต้องได้รับการประเมินเป็นกรณีๆ ไป ฉันสามารถบอกคุณว่าถึงจุดนี้ฉันได้พบกับ stares ว่างเปล่าเมื่อฉันแนะนำว่าตรรกะข้อ จำกัด ไม่ซ้ำ


2
เพิ่งออกจากงานและกำลังคิดที่จะขยายคำตอบของฉันให้มากขึ้นหรือน้อยลงในสิ่งที่คุณเพิ่งโพสต์ คำตอบที่ดี!
yannis

3

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

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


2

ฉันคิดว่าคุณทำทั้งสองเท่า

  • ข้อ จำกัด หลักควรอยู่ใน ORM - ภาษาการเขียนโปรแกรมมีความยืดหยุ่นมากขึ้นง่ายต่อการทดสอบและปรับแต่งง่ายขึ้นเมื่อความต้องการเปลี่ยนแปลง ไม่จำเป็นต้องกังวลเกี่ยวกับการแก้ไข DDL อย่างน้อย และโดยทั่วไปคุณหลีกเลี่ยงการทดสอบปัญหาการถดถอยของข้อมูลอย่างหนัก

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


1

ฐานข้อมูลเป็น IMO ที่เดียวที่ DRY สามารถถูกละเมิดได้เพราะถ้ามีบางอย่างที่ข้าม ORM ของคุณและมีข้อมูลที่ไม่ถูกต้อง จบเกม. การมีข้อมูลที่เสียหายคือการระเบิดฆ่า


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