PubTrivia เผยเบื้องหลังประกาศสีมาฐานข้อมูลซ้ำใน 2 ไฟล์
โปรเจกต์ PubTrivia แยก Next.js แอปพลิเคชันกับระบบ WebSocket เป็นสองส่วน ทำให้ต้องประกาศสาสน์ตั้งฐานข้อมูล Drizzle สองชุด และพบความต่าง 126 บรรทัดที่เป็นคอมเมนต์ทั้งหมด

ภาพประกอบจากคลังภาพสต็อก ไม่ใช่ภาพจากเหตุการณ์จริง
- PubTrivia แยก Next.js แอปและระบบ WebSocket ออกจากกันเด็ดขาด
- สาสน์ตั้งฐานข้อมูล Drizzle ถูกประกาศซ้ำในสองไฟล์เพราะเหตุผลด้านการ deploy
- ผลรัน diff พบความต่าง 126 บรรทัด แต่ทุกบรรทัดที่เป็นความต่างคือคอมเมนต์
- โครงสร้างตารางและชนิดข้อมูลทั้ง 8 ตารางตรงกัน 100% ไม่มีส่วนที่ทำให้ระบบรันพัง
โปรเจกต์ PubTrivia ทำงานโดยแยกส่วนแอปพลิเคชันหลักที่สร้างด้วย Next.js รันบนโฮสต์หนึ่ง ขณะที่กระบวนการประมวลผล WebSocket สำหรับจัดการซ็อกเก็ตและนาฬิการันเป็นกระบวนการยาวนานบนอีกโฮสต์หนึ่ง ทั้งสองส่วนถูก deploy จากรีโปสทอรีเดียวกันแต่แยกแพ็กเกจ ทำให้ตัวสร้างบิลด์ของระบบ WebSocket มองเห็นเฉพาะไดเรกทอรี ws-server/ เท่านั้น และไม่สามารถอิมพอร์ตสาสน์ตั้งฐานข้อมูลจากโฟลเดอร์หลักได้
ทางเลือกในการ deploy ลักษณะนี้ส่งผลให้เกิดความจำเป็นต้องประกาศสาสน์ตั้งฐานข้อมูลซ้ำสองชุด ไฟล์ทั้งสองเริ่มต้นด้วยข้อความอธิบายการมีอยู่ของอีกไฟล์ในรูปแบบที่ต่างกัน โดยไฟล์ในฝั่ง ws-server ระบุว่าเป็นสำเนาตั้งใจของไฟล์ utils/db/schema.ts ในแอปพลิเคชันหลัก เนื่องจากกระบวนการดังกล่าวถูกแยกเป็นอิสระและไม่มีการอิมพอร์ตข้ามแพ็กเกจ
เนื่องจากคอมเมนต์ไม่ใช่กลไกการทำงาน ผู้พัฒนาจึงได้วัดระยะห่างที่ไฟล์ทั้งสองคลาดเคลื่อนกันโดยใช้สคริปต์ขนาดเล็กในการดึงข้อมูล pgTable และชนิดข้อมูลแต่ละคอลัมน์มาเทียบเคียงกัน ผลปรากฏว่าจากตารางทั้ง 8 ตารางที่มีการประกาศในทั้งสองไฟล์ ไม่มีตารางใดเลยที่มีคอลัมน์เกินมา หรือมีชนิดข้อมูลที่แตกต่างกันแม้แต่จุดเดียวในส่วนที่จะส่งผลให้ระบบพังขณะรันไทม์

ภาพประกอบจากคลังภาพสต็อก ไม่ใช่ภาพจากเหตุการณ์จริง
ในฝั่งแอปพลิเคชันหลักมีการประกาศตารางเพิ่มอีก 3 ตาราง ได้แก่ บันทึกตรวจสอบความเป็นส่วนตัว บันทึกเซสชันการเข้าสู่ระบบ และสมาชิกทีม ซึ่งกระบวนการเกมไม่เคยอ่านข้อมูลเหล่านี้ การคัดลอกตารางกลุ่มนี้จึงเป็นเพียงการคัดลอกโค้ดที่ถูกละเลยเท่านั้น สำเนาจึงเป็นรูปแบบของเซตย่อยไม่ใช่ความเปลี่ยนแปลงที่อันตราย
การทำสาสน์ตั้งฐานข้อมูลหรือ Schema Duplication ในลักษณะนี้มักเกิดขึ้นในสถาปัตยกรรมแบบ Microservices หรือ Monorepo ที่มีการแยกบริการเดี่ยว (Standalone Service) ออกมาเพื่อความสะดวกในการจัดการทรัพยากรและการ deploy แม้จะช่วยลดปัญหาเรื่องการอิมพอร์ตโค้ดข้ามแพ็กเกจ แต่ความท้าทายสำคัญคือการรักษาความสอดคล้อง (Consistency) เมื่อโครงสร้างฐานข้อมูลเปลี่ยนแปลงในอนาคต
ความแตกต่างที่เหลือเกือบทั้งหมดจึงเป็นเรื่องของคำอธิบายหรือคอมเมนต์ เช่น เหตุผลที่คอลัมน์ plan หรือ stripe_id มีค่าว่างได้ หรือสถานะการสมัครสมาชิก subscription_status ที่กำหนดค่าเริ่มต้นเป็น trial โดยไฟล์สำเนาไม่ได้เก็บบันทึกเหตุผลเหล่านี้ไว้เลย ทำให้บันทึกคำอธิบายเหลือเพียง 19 บรรทัดเทียบกับ 77 บรรทัดในฝั่งหลัก
ความเสี่ยงและความผิดพลาดถูกจำกัดไว้ด้วยข้อจำกัดทางโครงสร้าง เนื่องจากไฟล์คอนฟิกูเรชัน Drizzle ระบุชื่อไฟล์เพียงไฟล์เดียว ทำให้สำเนาไม่สามารถสร้าง migration ได้เพราะไม่มีไฟล์ drizzle.config.ts ใน ws-server/ และไม่มีไลบรารี drizzle-kit ใน dependency ทำให้ความเบี่ยงเบนในสำเนาไม่สามารถทำลายฐานข้อมูลได้ แต่อาจเกิดกรณีการอ่านค่าคลาดเคลื่อนแทน
ที่มา: Dev.to
พบข้อมูลผิดพลาดในบทความนี้? แจ้งปัญหาบทความนี้
ความคิดเห็น
แสดงความคิดเห็น