การเรียกใช้แอปพลิเคชัน Hibernate ที่กำหนดค่าด้วยhbm2ddl.auto=update
เพื่ออัพเดตสกีมาฐานข้อมูลในสภาพแวดล้อมการทำงานจริงหรือไม่
การเรียกใช้แอปพลิเคชัน Hibernate ที่กำหนดค่าด้วยhbm2ddl.auto=update
เพื่ออัพเดตสกีมาฐานข้อมูลในสภาพแวดล้อมการทำงานจริงหรือไม่
คำตอบ:
ไม่มันไม่ปลอดภัย
แม้จะมีความพยายามอย่างดีที่สุดของทีมไฮเบอร์เนต แต่คุณก็ไม่สามารถพึ่งพาการอัปเดตอัตโนมัติในการผลิตได้ เขียนแพทช์ของคุณเองตรวจสอบด้วย DBA ทดสอบจากนั้นใช้ด้วยตนเอง
ในทางทฤษฎีหากการอัพเดต hbm2ddlทำงานในการพัฒนาก็ควรทำงานในการผลิตด้วย แต่ในความเป็นจริงมันไม่ได้เป็นอย่างนั้นเสมอไป
แม้ว่ามันจะทำงานได้ดี แต่มันอาจจะดีที่สุด DBA ได้รับเงินจำนวนมากด้วยเหตุผล
เราดำเนินการในการผลิตแม้ว่าจะมีแอปพลิเคชันที่ไม่ได้เป็นภารกิจที่สำคัญและไม่มี DBA ที่ได้รับค่าตอบแทนสูงในพนักงาน เป็นเพียงกระบวนการที่ดำเนินการด้วยตนเองน้อยกว่าที่เกิดจากความผิดพลาดของมนุษย์ - แอพพลิเคชั่นสามารถตรวจจับความแตกต่างและทำสิ่งที่ถูกต้องรวมทั้งคุณได้ทดสอบในการพัฒนาและทดสอบสภาพแวดล้อมต่าง ๆ
หนึ่ง caveat - ในสภาพแวดล้อมแบบคลัสเตอร์คุณอาจต้องการหลีกเลี่ยงเพราะหลาย ๆ แอพสามารถเกิดขึ้นพร้อมกันและลองแก้ไข schema ซึ่งอาจไม่ดี หรือใส่ในกลไกที่อนุญาตให้อัปเดตสคีมาได้เพียงอินสแตนซ์เดียวเท่านั้น
ผู้สร้างไฮเบอร์เนตกีดกันการทำเช่นนั้นในสภาพแวดล้อมการผลิตในหนังสือ"Java Persistence with Hibernate" :
คำเตือน: เราเห็นผู้ใช้ไฮเบอร์เนตกำลังพยายามใช้ SchemaUpdate เพื่ออัปเดตสคีมาของฐานข้อมูลการผลิตโดยอัตโนมัติ สิ่งนี้สามารถจบลงด้วยภัยพิบัติได้อย่างรวดเร็วและจะไม่ได้รับอนุญาตจาก DBA ของคุณ
ลองใช้ LiquiBase XML เพื่อดูการเปลี่ยนแปลงของการอัปเดต ฉันไม่เคยใช้มันมาจนถึงปีนี้ แต่ฉันพบว่ามันง่ายมากที่จะเรียนรู้และทำให้การควบคุมการแก้ไข / การโยกย้าย / การเปลี่ยนแปลงฐานข้อมูลแก้ไขได้ง่าย ฉันทำงานในโครงการ Groovy / Grails และ Grails ใช้ Hibernate สำหรับ ORM ทั้งหมด (เรียกว่า "GORM") เราใช้ Liquibase เพื่อจัดการการเปลี่ยนแปลง SQL schema ทั้งหมดซึ่งเราทำค่อนข้างบ่อยเนื่องจากแอปของเราพัฒนาด้วยคุณสมบัติใหม่
โดยทั่วไปคุณเก็บไฟล์ XML ของชุดการเปลี่ยนแปลงที่คุณยังคงเพิ่มต่อไปเมื่อแอปพลิเคชันของคุณวิวัฒนาการ ไฟล์นี้ถูกเก็บไว้ในคอมไพล์ (หรือสิ่งที่คุณกำลังใช้) กับส่วนที่เหลือของโครงการของคุณ เมื่อแอพของคุณถูกปรับใช้ Liquibase จะตรวจสอบว่าเป็นตารางการเปลี่ยนแปลงในฐานข้อมูลที่คุณกำลังเชื่อมต่อดังนั้นมันจะรู้ว่ามีอะไรบ้างที่ถูกนำไปใช้แล้วมันจะใช้สิ่งที่เซ็ตการแก้ไขใด ๆ มันใช้งานได้ดีมากในทางปฏิบัติและหากคุณใช้มันสำหรับการเปลี่ยนแปลงคีมาทั้งหมดของคุณคุณสามารถมั่นใจได้ 100% ว่ารหัสที่คุณชำระเงินและปรับใช้จะสามารถเชื่อมต่อกับสคีมาฐานข้อมูลที่เข้ากันได้อย่างสมบูรณ์
สิ่งที่ยอดเยี่ยมคือฉันสามารถใช้ฐานข้อมูล mysql แบบกระดานชนวนที่ว่างเปล่าบนแล็ปท็อปของฉันดับไฟแอพและติดตั้ง schema ให้ฉันทันที นอกจากนี้ยังทำให้ง่ายต่อการทดสอบการเปลี่ยนแปลง schema โดยใช้สิ่งเหล่านี้กับ local-dev หรือ staging db ก่อน
วิธีที่ง่ายที่สุดในการเริ่มต้นใช้งานอาจเป็นไปได้ที่จะใช้ฐานข้อมูลที่มีอยู่แล้วใช้ Liquibase เพื่อสร้างไฟล์ baseline.xml เริ่มต้น จากนั้นในอนาคตคุณสามารถผนวกเข้ากับมันและปล่อยให้ liquibase จัดการการเปลี่ยนแปลงสคีมา
hbm2ddl.auto=update
เพื่อให้การแมป Class / DB ของคุณได้รับการตรวจสอบและคุณสามารถควบคุมการสร้าง DB ได้อย่างสมบูรณ์ผ่าน liquibase คุณคิดอย่างไร?
validate
ฉันจะลงคะแนนไม่ ไฮเบอร์เนตดูเหมือนจะไม่เข้าใจเมื่อมีการเปลี่ยนแปลงประเภทข้อมูลสำหรับคอลัมน์ ตัวอย่าง (ใช้ MySQL):
String with @Column(length=50) ==> varchar(50)
changed to
String with @Column(length=100) ==> still varchar(50), not changed to varchar(100)
@Temporal(TemporalType.TIMESTAMP,TIME,DATE) will not update the DB columns if changed
อาจมีตัวอย่างอื่น ๆ ด้วยเช่นการผลักความยาวของคอลัมน์สตริงขึ้นไป 255 และเห็นมันแปลงเป็นข้อความสื่อข้อความ ฯลฯ ฯลฯ
ได้รับฉันไม่คิดว่าจะมีวิธี "แปลงประเภทข้อมูล" โดยไม่ต้องสร้างคอลัมน์ใหม่คัดลอกข้อมูลและลบคอลัมน์เก่าออกไป แต่นาทีฐานข้อมูลของคุณมีคอลัมน์ที่ไม่สะท้อนการทำแผนที่ไฮเบอร์เนตปัจจุบันที่คุณอาศัยอยู่มีอันตรายมาก ...
Flyway เป็นตัวเลือกที่ดีในการจัดการกับปัญหานี้:
@Column(length = 45)
@Column(length = 255)
สามารถตรวจสอบว่า Hibernate 4.3.6.Final hbm2ddl.auto=update
ปรับปรุงอย่างถูกต้องคีมาฐานข้อมูลโดยใช้ (สิ่งหนึ่งที่ต้องพูดถึงคือฐานข้อมูลไม่มีข้อมูลในขณะนี้ - เฉพาะโครงสร้าง)
ไฮเบอร์เนตจะต้องมีการปฏิเสธความรับผิดชอบเกี่ยวกับการไม่ใช้การปรับปรุงอัตโนมัติในผลิตภัณฑ์เพื่อให้ครอบคลุมตัวเองเมื่อคนที่ไม่รู้ว่าพวกเขากำลังใช้งานอะไรในสถานการณ์ที่ไม่ควรใช้
ได้รับสถานการณ์ที่ไม่ควรใช้มากกว่าจำนวนสถานการณ์ที่ตกลง
ฉันใช้มันมาหลายปีในโครงการต่าง ๆ มากมายและไม่เคยมีปัญหาเดียว นั่นไม่ใช่คำตอบที่อ่อนแอและไม่ใช่การเข้ารหัสคาวบอย มันเป็นความจริงทางประวัติศาสตร์
บุคคลที่กล่าวว่า "ไม่เคยทำในการผลิต" กำลังคิดถึงชุดการปรับใช้การผลิตที่เฉพาะเจาะจงนั่นคือสิ่งที่เขาคุ้นเคย (บริษัท ของเขาอุตสาหกรรมของเขา ฯลฯ )
จักรวาลของ "การปรับใช้การผลิต" นั้นกว้างใหญ่และหลากหลาย
ผู้พัฒนา Hibernate ที่มีประสบการณ์รู้ดีว่า DDL นั้นจะเป็นอย่างไรจากการกำหนดค่าการแมปที่กำหนด ตราบใดที่คุณทดสอบและตรวจสอบว่าสิ่งที่คุณคาดหวังนั้นสิ้นสุดลงใน DDL (ใน dev, qa, staging และอื่น ๆ ) คุณก็ใช้ได้
เมื่อคุณเพิ่มคุณสมบัติมากมายการอัพเดตสคีมาอัตโนมัติอาจช่วยประหยัดเวลาได้
รายการสิ่งที่อัปเดตอัตโนมัติจะไม่จัดการไม่มีที่สิ้นสุด แต่บางตัวอย่างเป็นการย้ายข้อมูลการเพิ่มคอลัมน์ที่ไม่สามารถยกเลิกได้การเปลี่ยนชื่อคอลัมน์ ฯลฯ
นอกจากนี้คุณต้องดูแลในสภาพแวดล้อมแบบคลัสเตอร์
แต่อีกครั้งถ้าคุณรู้ทุกสิ่งนี้คุณจะไม่ถามคำถามนี้ อืม . . ตกลงถ้าคุณถามคำถามนี้คุณควรรอจนกว่าคุณจะมีประสบการณ์มากมายเกี่ยวกับการปรับปรุง Hibernate และสคีมาอัตโนมัติก่อนที่คุณจะคิดถึงการใช้ใน Prod
ดังที่ฉันอธิบายในบทความนี้มันไม่ควรใช้hbm2ddl.auto
ในการผลิต
วิธีเดียวในการจัดการสกีมาฐานข้อมูลคือการใช้สคริปต์การย้ายข้อมูลแบบส่วนเพิ่มเนื่องจาก:
แม้แต่คู่มือผู้ใช้ไฮเบอร์เนตแนะนำให้คุณหลีกเลี่ยงการใช้hbm2ddl
เครื่องมือสำหรับสภาพแวดล้อมการผลิต
เราทำในโครงการที่ดำเนินการผลิตมาหลายเดือนแล้วและไม่เคยมีปัญหามาก่อน โปรดจำไว้ว่า 2 ส่วนผสมที่จำเป็นสำหรับสูตรนี้:
ออกแบบโมเดลวัตถุของคุณด้วยวิธีที่เข้ากันได้แบบย้อนหลังนั่นคือการคัดค้านวัตถุและคุณลักษณะมากกว่าการลบ / แก้ไข ซึ่งหมายความว่าหากคุณต้องการเปลี่ยนชื่อของวัตถุหรือคุณลักษณะให้ปล่อยชื่อเดิมตามที่เป็นอยู่เพิ่มชื่อใหม่และเขียนสคริปต์การย้ายข้อมูลบางประเภท หากคุณต้องการเปลี่ยนการเชื่อมโยงระหว่างวัตถุหากคุณมีการผลิตอยู่แล้วนั่นหมายความว่าการออกแบบของคุณผิดตั้งแต่แรกดังนั้นให้ลองคิดวิธีใหม่ในการแสดงความสัมพันธ์ใหม่โดยไม่กระทบกับข้อมูลเก่า
เสมอสำรองฐานข้อมูลก่อนที่จะมีการใช้งาน
ความรู้สึกของฉันคือ - หลังจากอ่านโพสต์นี้ - ว่า 90% ของผู้คนที่มีส่วนร่วมในการอภิปรายนี้รู้สึกตกใจเพียงกับความคิดที่จะใช้ระบบอัตโนมัติเช่นนี้ในสภาพแวดล้อมการผลิต บางคนขว้างลูกบอลที่ DBA ใช้เวลาสักครู่ในการพิจารณาว่าสภาพแวดล้อมการผลิตบางอย่างไม่สามารถให้บริการ DBA ได้และมีทีมพัฒนาไม่มากที่สามารถซื้อได้ (อย่างน้อยสำหรับโครงการขนาดกลาง) ดังนั้นถ้าเรากำลังพูดถึงทีมที่ทุกคนต้องทำทุกอย่างลูกบอลอยู่กับพวกเขา
ในกรณีนี้ทำไมไม่ลองมีประโยชน์กับทั้งสองโลกมากที่สุด เครื่องมือเช่นนี้อยู่ที่นี่เพื่อให้ความช่วยเหลือซึ่งด้วยการออกแบบและวางแผนอย่างรอบคอบสามารถช่วยเหลือได้ในหลายสถานการณ์ และเชื่อฉันเถอะผู้บริหารอาจจะโน้มน้าวใจได้ยาก แต่ถ้าพวกเขารู้ว่าลูกบอลไม่ได้อยู่ในมือพวกเขาจะรักมัน
โดยส่วนตัวฉันจะไม่กลับไปเขียนสคริปต์ด้วยมือเพื่อขยาย schema ประเภทใด ๆ แต่นั่นเป็นเพียงความคิดเห็นของฉัน และหลังจากเริ่มใช้ฐานข้อมูลแบบไม่มีสกีมา NoSQL เมื่อเร็ว ๆ นี้ฉันเห็นได้ว่าเร็ว ๆ นี้การดำเนินการตามสคีมาทั้งหมดจะเป็นของอดีตดังนั้นคุณควรเริ่มเปลี่ยนมุมมองของคุณและมองไปข้างหน้า
ฉันจะไม่เสี่ยงเพราะคุณอาจสูญเสียข้อมูลที่ควรรักษาไว้ hbm2ddl.auto = การอัพเดทเป็นวิธีง่าย ๆ ในการปรับปรุงฐานข้อมูล dev ของคุณให้ทันสมัย
ในกรณีของฉัน (Hibernate 3.5.2, Postgresql, Ubuntu) การตั้งค่าhibernate.hbm2ddl.auto=update
สร้างเฉพาะตารางใหม่และสร้างคอลัมน์ใหม่ในตารางที่มีอยู่แล้ว
มันไม่ได้วางตารางหรือวางคอลัมน์หรือเปลี่ยนคอลัมน์ มันสามารถเรียกได้ว่าเป็นตัวเลือกที่ปลอดภัย แต่สิ่งที่ชอบhibernate.hbm2ddl.auto=create_tables add_columns
จะชัดเจนกว่า
ไม่ปลอดภัยไม่แนะนำ แต่เป็นไปได้
ฉันมีประสบการณ์ในแอปพลิเคชันโดยใช้ตัวเลือกอัปเดตอัตโนมัติในการผลิต
ปัญหาหลักและความเสี่ยงที่พบในโซลูชันนี้คือ:
ดังนั้นฉันจะไม่แนะนำให้ใช้การอัปเดตอัตโนมัติในการผลิต
หากคุณต้องการใช้การอัพเดทอัตโนมัติในการผลิตจริง ๆ ฉันแนะนำ:
และต่างจากโพสต์อื่นฉันไม่คิดว่าการอัปเดตอัตโนมัติจะเปิดใช้งานซึ่งเกี่ยวข้องกับ DBA ที่ "ได้รับค่าตอบแทนดี" (ดังที่ได้กล่าวไว้ในโพสต์อื่น) DBA มีสิ่งที่สำคัญกว่าที่จะทำมากกว่าเขียนคำสั่ง SQL เพื่อสร้าง / เปลี่ยน / ลบตารางและคอลัมน์ งานประจำวันง่ายๆเหล่านี้สามารถทำได้และเป็นไปโดยอัตโนมัติโดยนักพัฒนาและส่งผ่านเฉพาะสำหรับทีม DBA เพื่อตรวจสอบโดยไม่จำเป็นต้องใช้ Hibernate และ DBA "จ่ายเงินดีมาก" เพื่อเขียน
ไม่ไม่เคยทำ ไฮเบอร์เนตไม่จัดการการย้ายข้อมูล ใช่มันจะทำให้สคีมาของคุณดูอย่างถูกต้อง แต่ก็ไม่แน่ใจว่าข้อมูลการผลิตที่มีค่าจะไม่สูญหายในกระบวนการ
โดยทั่วไปแล้วแอปพลิเคชันระดับองค์กรในองค์กรขนาดใหญ่จะทำงานโดยมีสิทธิ์ลดลง
ชื่อผู้ใช้ฐานข้อมูลอาจไม่มีDDL
สิทธิ์ในการเพิ่มคอลัมน์ที่hbm2ddl.auto=update
ต้องใช้
ฉันเห็นด้วยกับ Vladimir ผู้ดูแลระบบใน บริษัท ของฉันจะไม่ขอบคุณแน่นอนถ้าฉันยังแนะนำหลักสูตรดังกล่าว
นอกจากนี้การสร้างสคริปต์ SQL แทนการไว้วางใจแบบไฮเบอร์เนตทำให้คุณมีโอกาสลบฟิลด์ที่ไม่ได้ใช้งานอีกต่อไป ไฮเบอร์เนตไม่ได้ทำเช่นนั้น
และฉันพบว่าการเปรียบเทียบสคีมาการผลิตกับสคีมาใหม่ช่วยให้คุณมีความเข้าใจที่ดียิ่งขึ้นต่อการเปลี่ยนแปลงในรูปแบบข้อมูล แน่นอนคุณรู้เพราะคุณทำมัน แต่ตอนนี้คุณเห็นการเปลี่ยนแปลงทั้งหมดในครั้งเดียว แม้แต่คนที่ทำให้คุณเป็นเช่น "อะไรกันเนี่ย!"
มีเครื่องมือที่สามารถสร้างเดลต้าสคีมาให้คุณได้ดังนั้นมันจึงไม่ทำงานหนัก แล้วคุณก็รู้ว่าจะเกิดอะไรขึ้น
สคีมาของแอปพลิเคชันอาจมีการเปลี่ยนแปลงตามเวลา หากคุณมีการติดตั้งหลายอย่างซึ่งอาจเป็นเวอร์ชั่นที่แตกต่างกันคุณควรมีวิธีที่จะทำให้แน่ใจว่าแอปพลิเคชันของคุณเครื่องมือหรือสคริปต์บางประเภทสามารถย้ายสคีมาและข้อมูลจากรุ่นหนึ่งไปเป็นขั้นตอนต่อไปนี้
การมีความเพียรทั้งหมดของคุณในการจับคู่ไฮเบอร์เนต (หรือคำอธิบายประกอบ) เป็นวิธีที่ดีมากสำหรับการรักษาวิวัฒนาการของสคีภายใต้การควบคุม
คุณควรพิจารณาว่าวิวัฒนาการของสคีมานั้นมีหลายด้านที่ต้องพิจารณา:
วิวัฒนาการของสคีมาฐานข้อมูลในการเพิ่มคอลัมน์และตารางเพิ่มเติม
วางคอลัมน์ตารางและความสัมพันธ์เก่า ๆ
เติมคอลัมน์ใหม่ด้วยค่าเริ่มต้น
เครื่องมือไฮเบอร์เนตมีความสำคัญเป็นพิเศษในกรณี (เช่นในประสบการณ์ของฉัน) คุณมีแอพพลิเคชั่นรุ่นเดียวกันในฐานข้อมูลหลายประเภท
จุดที่ 3 มีความอ่อนไหวมากในกรณีที่คุณใช้ Hibernate เช่นเดียวกับในกรณีที่คุณแนะนำคุณสมบัติที่มีค่าบูลีนใหม่หรือตัวเลขถ้า Hibernate จะพบค่า Null ใด ๆ ในคอลัมน์ดังกล่าวหากจะยกข้อยกเว้น
ดังนั้นสิ่งที่ฉันจะทำคือ: จงใช้ความสามารถของเครื่องมือไฮเบอร์เนตของการอัพเดตสกีมา แต่คุณต้องเพิ่มข้อมูลและการเรียกกลับการบำรุงรักษาสกีมาเช่นเดียวกับการเติมค่าเริ่มต้นการเติมคอลัมน์ที่ไม่ได้ใช้แล้ว ด้วยวิธีนี้คุณจะได้รับประโยชน์ (สคริปต์อัพเดตฐานข้อมูลสกีมาอย่างเป็นอิสระและหลีกเลี่ยงการเข้ารหัสซ้ำของการอัปเดตในการคงอยู่และในสคริปต์) แต่คุณยังครอบคลุมทุกด้านของการดำเนินการ
ตัวอย่างเช่นหากการอัปเดตรุ่นประกอบด้วยเพียงการเพิ่มคุณสมบัติที่มีมูลค่า varchar (คอลัมน์ดังนั้น) ซึ่งอาจเริ่มต้นให้เป็นโมฆะด้วยการอัปเดตอัตโนมัติที่คุณจะทำ ในกรณีที่จำเป็นต้องมีความซับซ้อนเพิ่มขึ้นจะต้องทำงานเพิ่มเติม
นี่คือการสมมติว่าแอปพลิเคชันเมื่ออัปเดตมีความสามารถในการอัปเดตสคีมาของมัน (ซึ่งสามารถทำได้) ซึ่งหมายความว่ามันจะต้องมีสิทธิ์ของผู้ใช้ในการทำสคีมา หากนโยบายของลูกค้าป้องกันกรณีนี้ (น่าจะเป็น Lizard Brain case) คุณจะต้องจัดเตรียมสคริปต์เฉพาะฐานข้อมูล