ฐานข้อมูลเชิงสัมพันธ์และการพัฒนาซ้ำ


19

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

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

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

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

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

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

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

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

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


6
บังเอิญฉันไม่คิดว่ามันจะเกี่ยวข้องกับฐานข้อมูลเชิงสัมพันธ์โดยเฉพาะ ฉันมีปัญหาที่คล้ายกันกับโครงการที่ฉันกำลังดำเนินการอยู่ แต่เรากำลังมี schema สำหรับสตริง JSON ของเราที่แสดงถึงวัตถุที่ไม่สัมพันธ์กันมาก มันอาจส่งผลต่อความเพียรทุกรูปแบบอย่างเท่าเทียมกัน
Ixrec

1
คุณสามารถเปลี่ยนคีมาฐานข้อมูลในทางที่ไม่สูญเสียข้อมูลที่เป็นen.wikipedia.org/wiki/Schema_migration
RemcoGerlich

1
ฉันแน่ใจว่าหัวข้อนี้มีการพูดคุยกันอย่างกว้างขวางก่อนหน้านี้ไม่พบในโปรแกรมเมอร์ แต่ดูที่นี่martinfowler.com/articles/evodb.htmlหรือstackoverflow.com/questions/334059/
Doc Brown

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

คำตอบ:


15

ไม่จำเป็นต้องเป็นคลาสพิเศษ แต่ใช่คุณต้องการบางสิ่งที่จะใช้ฐานข้อมูลในรูปแบบก่อนหน้าและแปลงเป็นรูปแบบปัจจุบัน

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

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

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

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

@Doc Brown เชื่อมโยงMartin Fowler แล้ว: การออกแบบฐานข้อมูลวิวัฒนาการและ/programming/334059/agile-development-and-database-changesและฉันจะเพิ่มAlex Papadimoulis: การเปลี่ยนแปลงฐานข้อมูลเสร็จสิ้นซึ่งสั้นกว่า และมีตัวอย่างบางส่วน

เป็นตัวอย่างที่ดีของการใช้เครื่องมือกระบวนการดังกล่าวผมขอแนะนำalembic มันขึ้นอยู่กับกรอบงานPython SQLAlchemyแต่คุณสามารถใช้กับภาษาและกรอบงานอื่น ๆ ได้หากพวกเขาไม่มีการสนับสนุนการย้ายข้อมูลของตัวเอง หน้าวิกิพีเดียSchema โยกย้ายแสดงรายการเครื่องมือดังกล่าวมากขึ้น


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

1
ยกนิ้วให้กับบทความของอเล็กซ์; มันอาจจะไม่สั้นลง แต่มันทำให้การอ่านเชิงปฏิบัติและความบันเทิงมากขึ้น
เมอร์ฟีมี. ค.

1
เราเป็นร้าน Agile และเราให้บริการ uptime 100% และทั้งสองนั้นใช้กับฐานข้อมูลเช่นกัน เราโอนย้ายสคีมาการผลิตโดยเฉลี่ยวันละครั้งและฉันจะให้ทุกอย่างที่สองที่ Jan พูด อีกสิ่งหนึ่งที่เราทำอย่างนั้นประเมินค่าไม่ได้คือสิ่งที่เราเรียกการทดสอบการย้ายข้อมูลซึ่งทำงานเป็นส่วนหนึ่งของกระบวนการสร้างและปรับใช้ของเรา ใช้สแนปชอตของการผลิตปิดใช้การย้ายใด ๆ ที่ค้างอยู่จากต้นแบบไปยังจากนั้นเรียกใช้การทดสอบหน่วยจากรหัสการผลิตที่ปรับใช้ในปัจจุบันกับสคีมานั้น เป้าหมายคือการตรวจสอบว่าการใช้การย้ายข้อมูลจะไม่ทำให้ระบบการทำงานเสียหาย
Gordon Wrigley

1

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

ก่อนอื่นฐานข้อมูลเชิงสัมพันธ์จะ จำกัด รูปแบบข้อมูลมากเกินไปทำให้การเปลี่ยนแปลงยากมากหรือไม่?

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

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

สิ่งนี้นำไปสู่ส่วนที่สองของคำถามซึ่งเป็นข้อสมมติที่มากกว่าจริง ๆ แต่ควรถูกมองว่าเป็นคำถาม: เราควรจะทำให้โมเดลโดเมนของเราเสร็จสิ้นในครั้งแรกหรือไม่

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

ในหลายวิธีการย้ายไปยังโซลูชันฐานข้อมูล "No SQL" เป็นผลมาจากปัญหาของการเชื่อมโยงกันของตัวแบบข้อมูล การใช้ object-oriented ไม่มีวิธี SQL ทำให้เราคิดเกี่ยวกับการทำแผนที่ระหว่าง object ของเรากับ code และในโลกแห่งความเป็นจริง - และเมื่อเราพบความไม่ลงรอยกันมันมักจะชัดเจนในตัวเองเพราะมันเป็นไปไม่ได้ ฐานข้อมูล สิ่งนี้นำไปสู่การออกแบบโดยรวมที่ดีขึ้น

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

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


1
ฉันหวังว่าคุณจะมีปัญหาในการสร้างเขตข้อมูลใหม่ในตาราง RDBMS เพื่อทำให้คำสั่งนั้นน่าทึ่งยิ่งขึ้น ตารางฐานข้อมูลจะต้องมีความพิเศษมาก (หรือประเภทของเขตข้อมูลใหม่จะต้องเป็นสิ่งที่พิเศษ) เพื่อสร้างปัญหาเพื่อเพิ่มหนึ่งเขตข้อมูล
Alexey Zimarev

ใช่ แต่มันไม่ได้เป็นเพียงแค่หนึ่งช่อง ...
theMayer

1
ฉันจะบอกว่าบ่อยครั้งมันเป็นเพียงหนึ่งในเขตข้อมูล การเปลี่ยนแปลงคีมาที่น่าทึ่งไม่ได้เกิดขึ้นบ่อยนัก ฉันไม่ได้เป็นแฟนของการใช้ RDBMSes กับการออกแบบ OO เนื่องจากความต้านทานไม่ตรงกัน อย่างไรก็ตามการเพิ่มประเภทใหม่ (ตาราง) และคุณสมบัติ (คอลัมน์) นั้นค่อนข้างง่ายในทั้งสองโลกแม้ว่าใน NoSQL มันง่ายกว่าเล็กน้อย แต่การเปลี่ยนแปลงที่ซับซ้อนเป็นความเจ็บปวดในทั้งสองกรณี ยิ่งแย่ไปกว่านั้นมันจะกลายเป็นระบบที่มาจากเหตุการณ์ด้วยสแนปชอตตรงกันข้ามกับความพึงพอใจในประสบการณ์การพัฒนาระบบดังกล่าว
Alexey Zimarev

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

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

-1

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

สิ่งนี้จะช่วยให้คุณมี 2 ตัวเลือกหลักในการจัดการกับการเปลี่ยนแปลงครั้งใหญ่เมื่อมาถึง: สิ่งแรกคือการสร้างเลเยอร์ DB เป็น API ใช้ขั้นตอนการจัดเก็บเพื่อให้สามารถเปลี่ยนแปลงได้เพื่อให้เหมาะกับลูกค้าโดยไม่ต้องเปลี่ยนโครงสร้างข้อมูล

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

ดังนั้น: 1. พยายามคิดล่วงหน้าด้วยการออกแบบดังนั้นคุณไม่จำเป็นต้องเปลี่ยนแปลงอะไร

  1. พึ่งพา wrappers หรือ API ดังนั้นการเปลี่ยนแปลงมี จำกัด หรือสามารถซ่อนอยู่ภายในคอมโพเนนต์ที่แยกได้

  2. ใช้เวลาในการอัพเกรดอย่างถูกต้องหากคุณต้องการ

ขั้นตอนเหล่านี้ใช้กับทุกสิ่งไม่ใช่เฉพาะฐานข้อมูล


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

@JanHudec ตั้งแต่เมื่อ SP ไม่ได้อยู่ในการควบคุมเวอร์ชัน? คุณสามารถครอบคลุมสิ่งต่าง ๆ ได้คุณเปลี่ยน SP API เพื่อนำสตริงและเขียนไปยังฟิลด์อื่นจัดการหมายเลขเก่าและสตริงใหม่ในรหัสบิตใน SP ของคุณ ไม่ใช่วิธีที่ดีที่สุด แต่สามารถดีกว่าไปยังทุกไซต์ลูกค้าเพื่อโยกย้ายข้อมูลของพวกเขาไปยังรูปแบบสตริงใหม่ (มีตัวอย่างที่ดีกว่า แต่คุณเข้าใจแล้ว) หากการเปลี่ยนแปลงมีขนาดใหญ่คุณต้องโยกย้าย แต่อย่างน้อยก็ด้วย DB API ที่คุณมีตัวเลือกอื่น ๆ ราคาถูกกว่าด้วย
gbjbaanb

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