SQL Database design ที่ผมเรียนมามันไม่ครบ
ตอนผมเรียนมหาลัย ผมได้เรียนวิธีออกแบบ schema ในฐานข้อมูล, วิธีการใช้ ER diagram อธิบาย database design ของผม, รวมถึงการออกแบบ query ต่าง ๆ เพื่อให้มีประสิทธิภาพสูง เรียกรวม ๆ กันว่า การ design database ในปัจจุบัน หมายถึง ณ ตอนนี้ที่โปรแกรมทำงานแบบนี้ database ที่มีประสิทธิภาพสูงสุดสำหรับโปรแกรมตอนนี้หน้าตาอย่างไร
สิ่งที่หายไปคือ ผมไม่เคยเรียนวิธี design ให้ database รองรับอดีตและอนาคตของโปรแกรมเลย
ปัญหาที่ตามมาก็คือ เวลา deploy โปรแกรมเวอร์ชั่นถัดไปก็จะมี down time เพราะ database ที่ผมออกแบบมาเวิร์คกับโปรแกรมเวอร์ชั่นใหม่เท่านั้น ทำให้ผมต้องหยุดให้บริการ, deploy ทั้งแอพพลิเคชันและ database ให้เสร็จแล้วถึงจะให้บริการต่อได้ อันนี้คือกรณีที่ผมโชคดี deploy สำเร็จนะ ถ้าโชคร้ายเจอปัญหาที่แก้ไม่ได้แล้วต้อง rollback ก็ต้องหยุดให้บริการเพื่อ rollback อีก ซึ่งจากข้อจำกัดทั้งหมดนี้ ทำให้ผมต้องเลือกไป deploy ในช่วงที่มีลูกค้าใช้บริการน้อย ๆ ซึ่งปรกติก็จะเป็นกลางคืนหรือไม่ก็เสาร์ อาทิตย์ ซึ่งไม่ใช่ช่วงเวลาที่ทำสมาธิได้ง่ายเลย ทำให้ความเสี่ยงในการ deploy สูงขึ้นมาก
ออกแบบ database ให้รองรับอนาคต
การออกแบบ database ให้รองรับการ deploy ที่จะเกิดขึ้นในอนาคต (หวังว่าจะเป็นอันใกล้) ทำได้โดยการแยกการ deploy database และการ deploy แอพพลิเคชันออกจากกัน
ที่เราอยากทำแบบนี้เพราะทุก ๆ change ที่เกิดขึ้นบน production มีความเสี่ยง ยิ่งเราลดขนาด change ให้เล็กเท่าไหร่ โอกาสที่จะ deploy ได้อย่างราบรื่นก็ยิ่งสูงเท่านั้น ซึ่งถ้าเราอยากจะ deploy database changes ก่อนแอพพลิเคชัน นั่นแปลว่าเราต้องออกแบบ database ให้รองรับอดีตด้วย
การออกแบบ database ให้รองรับอดีต
การออกแบบ database ให้รองรับอดีต คือการเพิ่มอย่างเดียว ไม่มีลบ เช่น ถ้าเราต้องการเปลี่ยนชื่อ column เราต้องแยกการ deploy การเพิ่ม column ใหม่ใน deployment แรก ออกจากการลบ column เก่าใน deployment ที่สอง
นอกจากนี้แอพพลิเคชันที่เราเขียน จะต้องเขียนให้รองรับทั้ง database เวอร์ชั่นเก่าและใหม่ เช่นเช็คว่าถ้าเจอ column ชื่อเก่าหรือใหม่ ก็เขียนลง column นั้น
การ deploy ที่จะเกิดขึ้นก็จะเป็นดังนี้
- deploy การเพิ่ม column ใหม่ใน database (ยังไม่ใช้)
- deploy แอพพลิเคชันที่รองรับการเขียนลง database เวอร์ชั่นใหม่
- migrate data จาก column เก่าไปใหม่
- ลบ column เก่า
ซึ่งขั้นที่ 1 และ 2 สามารถสลับที่กันได้ นี่แหละคือการลดความเสี่ยงด้วยการแยกการ deploy database และแอพพลิเคชันออกจากกัน
ผมได้เรียนรู้จากหนังสือ the DevOps Handbook ว่า IMVU เป็นคนนึงในอีกหลาย ๆ คนที่ทำสิ่งนี้ ซึ่งส่งผลทำให้พวกเค้า deploy ได้วันละ 50 ครั้งในปี 2009 ซึ่งสามารถทำได้ในเวลางานที่ทุกคนอยู่กันพร้อมหน้า และอยู่ในสภาพสดชื่นพร้อมรับทุกสถานการณ์ที่ไม่คาดฝัน
สรุปแล้วการออกแบบ database ให้รองรับอดีต, ปัจจุบันและอนาคต ก็เหมือนการออกแบบ deployment experience นั้นเอง ถ้าเราทำตรงนี้ได้ดี ร่วมกันกับเทคนิคการ deploy เช่น blue/green deployment ก็จะทำให้เราสามารถ deploy แบบ zero downtime (ไม่ต้องหยุดให้บริการ) ได้ ซึ่งเป็นบันไดขั้นพื้นฐานสู่เทคนิคขั้นต่อ ๆ ไป เช่น canary release ไปจนถึงการแยก deployment กับ release ออกจากกันเพื่อเพิ่มความยืดหยุ่นในการทำ business release เพื่อความคล่องตัวทางธุรกิจต่อไป