รุ่นต่อตารางฐานข้อมูล?


11

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

แทนที่จะเป็นรุ่นต่อตัวควบคุมหรือรุ่นเล็ก ๆ หลายตัวที่ใช้ร่วมกัน

ตัวอย่างถ้าฉันมี model model get_user ($ user_id) ฉันสามารถเขียนมันบน users_models.php ...

ข้อเสียอย่างหนึ่งที่ฉันเห็นในที่นี้คือฉันอาจต้องโทรหลายรุ่นแทนที่จะเป็นแค่ชื่อผู้ใช้งาน

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

หมายเหตุ: มีคำถามที่คล้ายกัน แต่ไม่ครอบคลุมถึงโมเดลต่อตารางฐานข้อมูล

คำตอบ:


8

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


เพียงเล็กน้อยของภาคผนวก - มันถือว่าเป็นรูปแบบการต่อต้านโดย Martin Fowler Fullstop ที่นี่ เขามีความเข้าใจอย่างถ่องแท้เกี่ยวกับกรณีนี้ แต่นั่นไม่ได้หมายความว่ามันไม่ดี - แตกต่างจาก God Object ซึ่งเกือบจะไม่ดีเสมอไปบางครั้งโครงสร้างแบบนี้บางครั้งก็มีประโยชน์และไม่น่าเชื่อ ฉันไม่คิดว่านี่เป็นรูปแบบการต่อต้านเลย
T. Sar

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

7

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

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

และฉันจะบอกว่าถ้าคุณมีหนึ่งตาราง SQL ต่อวัตถุธุรกิจก็เป็นไปได้ว่าโครงสร้างฐานข้อมูลของคุณจะไม่ได้มาตรฐาน


3

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

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

สิ่งนี้นำไปสู่ส่วนแรกของคำตอบของ Marjan Venema:

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

โลหิตจางโดเมนรุ่นเป็นรูปแบบการป้องกัน "โมเดลต่อตาราง" ตามที่ Venema แนะนำอาจถูกมองว่าเป็น "การสร้างฐานข้อมูลของคุณใหม่" แต่มันไม่ถูกต้องอย่างแน่นอนที่จะบอกว่าสิ่งนี้เพียงอย่างเดียวคือ Anemic Domain Model

จาก Martin Fowler:

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

(เน้นฉัน)

ปัจจัยสำคัญในโมเดลโดเมนโลหิตจางคือการขาดพฤติกรรมหรือวิธีการในคลาส Domain Model

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

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

และคำตอบก็คือการรวมราก มาร์ตินฟาวเลอร์ฯ :

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

(เน้นฉัน)

"คลัสเตอร์ของวัตถุโดเมน" สามารถดูได้ใน "รูปแบบโดเมนที่จับคู่กับหลายตาราง" พฤติกรรมที่มีผลต่อหลายตารางควรกำหนดไว้ใน Aggregate Root - คลาสที่ห่อหุ้ม "สิ่ง" ที่มีผลต่อหลายตารางหรือวัตถุ:

อีกครั้งจาก Martin Fowler:

การรวมมักจะมีคอลเลกชัน mutliple พร้อมกับฟิลด์ง่าย ๆ

เพื่อตอบคำถามเดิมของ OP:

... การสร้างแบบจำลองต่อตารางฐานข้อมูลถือว่าเป็นแนวปฏิบัติที่ดีหรือไม่ วิธีนั้นจะไม่ถูกเขียนสองครั้ง

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

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

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