แชร์

Database design for multi-tenant Cloud ERP

อัพเดทล่าสุด: 19 ม.ค. 2025
1 ผู้เข้าชม

วันนี้กัลยามิตรได้แชร์คลิป "เต้าเต๋อจิง" มาให้ คลิปนี้ผมไม่เคยรับฟังมาก่อน พอดีกับช่วงจังหวะเวลาที่คิดผ่อนปรนตัวเอง อยากทบทวนเพื่อเตรียมเส้นทางเดินลงเขา
 
อาจารย์วีระ เขียนบทความเมื่อไม่นานมานี้ เล่าถึงนิทานในพระสูตรเรื่องคนตาบอดคลำช้าง เปรียบเสมือนใช้ประสบการณ์ความรู้เท่าเรามีตีความโลกที่เราเห็น แล้วผมมีความคิดสงสัยต่อไป ถ้าเอาคนตาดีมาอธิบายช้างที่เขาเห็น คนตาบอดแต่ละคนจะปั้นรูปช้างออกมาเป็นแบบไหนกันบ้าง
 
สำหรับ "เต้าเต๋อจิง" ผมเป็นเหมือนคนตาบอดได้แต่ครุ่นคิดตาม คนตาดีที่เคยเห็นช้างมีวิธีอธิบายไม่เหมือนกัน ยิ่งมีโอกาสรับฟังความคิดเห็นหลายด้านก็ช่วยต่อเติมให้สมบูรณ์ยิ่งขึ้น
 
มียอดเขาหนึ่งที่ผมมุ่งเดินขึ้นตลอดช่วงวาระการทำงาน คือการเขียนและออกแบบโปรแกรม จึงรู้จักคุ้นเคยดีในเส้นทางสายนี้ กล่าวได้ว่าเป็นทางเปลี่ยวสายหนึ่ง ที่ไม่ค่อยได้พบเห็นใครเลือกทางนี้ สิ่งที่ผมทำเกิดจากการตีความตามโลกที่มองเห็น แต่เมื่อเล่าออกมาแล้วจะถูกเข้าใจอย่างไรก็เป็นอีกเรื่องหนึ่ง
 
ทำโปรแกรม Cloud เพื่อให้บริการ สำหรับผมไม่เหมือนกับงานโปรเจกท์ที่มีสเปคเป็นเป้าหมายให้หยุด เส้นทางนี้เดินไปเรื่อย ๆ ไม่มีเส้นชัย ไม่มีจุดสิ้นสุด ต้องปรับตัวให้คิดถึงการยืนระยะดูแลโปรแกรมได้ยาวนาน พยายามมองให้ไกลที่สุด คาดเดาถึงสิ่งที่เกิดขึ้นในอนาคต กลายเป็นความสุดโต่งอย่างหนึ่ง อาจจะมีโชคอยู่บ้าง ที่บังเอิญมีขั้วตรงข้ามมาช่วยเหนี่ยวรั้งไว้ เพื่อนร่วมงานผู้เชื่อกับการทำปัจจุบันให้ดีที่สุด มีพรสวรรค์ในการรับมือแก้ปัญหาตามเหตุปัจจัย ไม่ค่อยเห็นด้วยกับการใช้พลังกับสิ่งที่ยังไม่เกิด มักรู้สึกขำกับความพยายามจินตนาการถึงผู้ใช้ในอนาคต ช่วยให้งานโปรแกรมที่ออกมาไม่หลุดไปไกลเกินการรับรู้ของผู้คนทั่วไป
 
บัญชี หรือ ERP?
 
ปี 2012 ผมเริ่มคิดว่าจะทำโปรแกรม Cloud เป็นช่วงเวลาที่ internet ยังไม่แพร่หลายในออฟฟิศทั่วไป เป็นช่วงรอยต่อระหว่าง iPhone 4 ที่ใช้สัญญาณ 3G กับ iPhone 5 ที่รองรับ 4G LTE รออีกหนึ่งปี 2013 ประเทศไทยจึงเริ่มมีบริการ 4G ผมนึกภาพคอมพิวเตอร์ในออฟฟิศทุกเครื่องเชื่อมต่ออินเตอร์เน็ต ทำงานโดยใช้โปรแกรมที่เป็น web app ความยากอยู่ที่การนำเสนอให้ผู้ใช้เชื่อว่าเป็นไปได้ ไม่ต้องติดตั้งโปรแกรมลงเครื่อง ไม่ต้องซื้อ server มาตั้งเอง ข้อมูลไม่โดนขโมยหรือสูญหาย ไม่รู้ว่าต้องใช้แต้มบุญเท่าไหร่ โชคดีที่หน้าที่นี้ไม่ใช่ของผม
 
คิดถึงคำป๋าเต็ด วิชามวยวัด ผสมปนเปประสบการณ์หลากหลาย เอามาหลอมรวมจนเกิดเป็นกระบวนท่าของตัวเอง ไม่มี how to หรือ best practice ให้เรียนรู้ได้แต่ลองผิดลองถูกแล้วโชคดีที่รอดมาได้ ภายหลังเมื่อมีสตาร์ทอัพทำ Cloud ERP ออกมามากมาย ผมเคยไปงานมีตอัพกลุ่มโปรแกรมเมอร์ ถูกถามว่าใช้ software stack อะไร แล้วผมตอบไม่ได้ อีกครั้งหนึ่งต้องให้ข้อมูลกับออดิทเตอร์ที่มาตรวจระบบภายในของลูกค้า ถูกถามว่าเป็น PaaS (Platform as a Service) หรือ SaaS (Software as as Service) ผมก็ไม่แน่ใจอีกเหมือนกัน เรื่องตลกกว่านั้นผมเคยถามเพื่อนร่วมงานที่ดูแลลูกค้า ว่าที่เราทำอยู่นี่เป็นโปรแกรมบัญชี หรือ ERP เขายิ้มแล้วตอบว่า ก็แล้วแต่ลูกค้า
 
โปรแกรมบัญชี ต่างจาก ERP มากมายนักในทัศนะของผม แต่คนทั่วไปอาจไม่ได้คิดมากขนาดนั้น เหมือนกับคนที่ไม่อยู่ในแวดวงหมอก็ไม่คิดว่าหมอกับพยาบาลต่างกัน สำหรับผมขึ้นอยู่กับวัตถุประสงค์ของผู้ใช้ ถ้าผู้ใช้หลักที่ผลักดันโปรแกรมมาจากฝ่ายบัญชี ก็มักจะโน้มเอียงเพื่อตอบสนองงานส่วนนั้นก่อน มีสัดส่วนของความเป็นโปรแกรมบัญชีเยอะหน่อย เป็นส่วนของช้างที่ถูกบอกเล่าจากฝ่ายบัญชี
 
ลักษณะที่สำคัญของ ERP อยู่ตรงที่กระจายงาน สลายความซ้ำซ้อน โดยแชร์ข้อมูลที่ใช้ประโยชน์ร่วมกันได้ ดังนั้นในการบันทึกข้อมูลสำหรับงานใด ๆ จะมีข้อมูลอยู่ 3 ประเภท
 
ข้อมูลที่ตนเองใช้ แต่ผู้อื่นไม่ได้ใช้ 
ข้อมูลที่ตนเองใช้ และผู้อื่นใช้ 
ข้อมูลที่ตนเองไม่ใช้ แต่ผู้อื่นใช้
 
จะเห็นว่าการออกแบบให้เป็น ERP สำหรับงานที่ไม่อยู่ในฝ่ายบัญชี จะคำนึงถึงประโยชน์การใช้งานของเจ้าของข้อมูล และเผื่อแผ่ไปถึงผู้อื่นที่มีส่วนร่วม ไม่ใช่การออกแบบแค่ให้ฝ่ายบัญชีใช้ โดยลืมดูว่าเจ้าของงานใช้ประโยชน์ได้หรือไม่
 
บางครั้งเราก็ออกแบบให้แบ่งเบางานออกจากฝ่ายบัญชี โดยการโอนไปให้ฝ่ายอื่นที่เป็นต้นเรื่องรับผิดชอบแทน เช่น ให้ฝ่ายขายเปิดบิลเอง หรือฝ่ายสโตร์ช่วยบันทึกรับสินค้า เบิกสินค้า หากวัตถุประสงค์ยังได้เพียงผลลัพธ์ทางบัญชี ก็ไม่ต่างจากโปรแกรมบัญชีที่ใช้เสมียนทำ ฝ่ายสโตร์อาจต้องการบันทึกสินค้าชำรุด แต่ไม่สามารถทำในโปรแกรม ต้องแยกมาทำเวิร์กชีตคุมเอง เพราะโปรแกรมมีแค่ยอดสต็อคบัญชี
 
อย่างไรก็ตามบัญชีก็เป็นหัวใจของธุรกิจ ในกิจการส่วนใหญ่ถือว่าเป็นงานส่วนที่สำคัญกว่าส่วนอื่น ข้อมูลทางบัญชีสามารถหยิบยืมไปใช้ประโยชน์ หรือใช้เป็นหลักฐานอ้างอิงที่เชื่อถือได้ ไม่ได้ผิดเพี้ยนจนรับไม่ได้ ในองค์กรที่ไม่ใหญ่ ไม่มีความเป็นแผนกหรือฝ่ายที่ชัดเจน ไม่อยู่ในธุรกิจที่แข่งขันสูง ไม่มีกระบวนการทำงานที่ซับซ้อน แค่โปรแกรมที่ใช้ประโยชน์ด้านบัญชี แต่ช่วยกันทำงานได้ก็เพียงพอแล้ว เรื่องนี้เพื่อนของเราบอกว่า "สำหรับทุกคน (เราและลูกค้า)​ ถ้าคำว่าโปรแกรม ERP ดูดีกว่า ก็ไม่เห็นจะมีปัญหาอะไร"
 
เล่าจื้อบอกว่า เพราะว่างเปล่าจึงใช้ประโยชน์ได้
 
ในองค์กรใหญ่ ฝ่ายอื่นอาจมีเรื่องเล่าถึงช้างที่แตกต่าง เช่น ผู้จัดการฝ่ายขายต้องการวิเคราะห์ประสิทธิภาพของเซล อัตราส่วนของใบเสนอราคาที่สามารถปิดการขายสำเร็จ เวิร์กโฟลว์ก็จะต้องออกแบบมีใบเสนอราคา ซึ่งเป็นเอกสารที่ไม่เกี่ยวกับงานบัญชี หรือคลังสินค้าต้องการจัดระบบโซนนิ่งเพื่อหยิบสินค้า ข้อมูลสินค้าก็จะต้องเก็บข้อมูลรหัสพื้นที่ในโกดัง เพื่อใช้แสดงเมื่อต้องจัดระบบหยิบสินค้า หรือ ฝ่ายจัดส่งต้องการให้แยกพื้นที่ส่งสินค้า เพื่อใช้วางแผนจัดรถขนส่ง ข้อมูลลูกค้าก็จะต้องมีรหัสของพื้นที่จัดส่ง
 
เมื่อคิดถึงการออกแบบโปรแกรมให้กับคนที่อยากได้ช้างส่วนที่เขาต้องการ จึงเป็นไปไม่ได้ที่จะทำโปรแกรม ERP โดยมีคิดเมนูและรายงานมาตรฐานเตรียมไว้ก่อน เพราะแต่ละฝ่ายแต่ละแผนกมีงานไม่เหมือนกัน เรื่องนี้ง่ายมากสำหรับผม อะไรที่ไม่ใช่มาตรฐาน จะถูกตัดออกให้เป็นงาน customize ภายหลัง สุดท้ายเมื่อถอดระบบบัญชีออกไปด้วย ก็เหลือโปรแกรมว่าง ๆ เหมือนห้องไม่มีเฟอร์นิเจอร์อะไรเลย ครั้งหนึ่งเพื่อนร่วมงานบอกว่าอยากให้ผมได้เห็นสีหน้าลูกค้าตอนที่ต้องโชว์โปรแกรมไม่มีอะไรให้ดู
 
สำหรับผมโปรแกรมบัญชี เพื่อใช้งานบัญชี แต่ ERP นั้นเพื่อทุกคน เริ่มต้นจากว่างเปล่า จนกว่าจะถูก implement ให้เข้ากับความต้องการของผู้ใช้ ซึ่งแปรผันได้ร้อยพันกระบวนท่า หลายครั้งผมเห็นทีมวางระบบเริ่มต้นจากระบบของฝ่ายอื่นก่อน แล้วเก็บงานฝ่ายบัญชีไว้หลังสุด เมื่อถึงตอนนั้นข้อมูลจะไหลมารวมโดยไม่ต้องออกแรงมาก เหลือแค่รวบรวม transaction ที่เกิดจากฝ่ายต่าง ๆ มาสรุปตรวจทานตามรอบภาษีและบัญชี
 
ความหมายของ Multi-tenant
 
Multi-tenant Cloud ERP จึงมีที่มาจากการเห็นว่าแก่น ERP นั้นว่างเปล่า แม้กระทั่งระบบบัญชีก็เป็นเพียงกิ่งก้านที่เอามาต่อเติมภายหลัง การออกแบบในระดับนี้จึงแยกออกจาก Business Logic แต่อาศัยการสร้างเครื่องมือพื้นฐานที่ช่วยให้ทีมวางระบบสามารถ customize ได้ตาม Logic ของแต่ละกิจการโดยไม่ต้องย้อนมาเป็นงานเขียนโปรแกรมเพิ่ม
 
ไอเดียนี้แตกต่างจาก ERP ที่ใช้งานบน Cloud อื่นอย่างไร โปรแกรมขนาดใหญ่อย่าง SAP, Dynamic หรือ Odoo เมื่อต้องการใช้งานบน Cloud จะต้องติดตั้งโปรแกรมมาตรฐานใช้งานเป็น Private Cloud คล้ายกับการติดตั้งโปรแกรมลง Server ของตัวเอง เมื่อใช้งานไปเรื่อย ๆ อาจมีการ customize ดัดแปลง เพิ่มเติมงานที่ไม่มีอยู่ในโปรแกรมมาตรฐาน กลายเป็นโปรแกรมรุ่นที่มีความสามารถพิเศษ ปัญหาที่จะเจอในอนาคต เมื่อมีการอัพเดทโปรแกรมที่เป็นระบบพื้นฐาน งานส่วนที่ดัดแปลงเหล่านั้นอาจเข้ากันไม่ได้ ยิ่งใช้โปรแกรมยาวนานเท่าไหร่งานดัดแปลงเหล่านั้นก็เป็นภาระที่หาคนดูแลยากและมีค่าใช้จ่ายสูงขึ้นเรื่อย ๆ

 


 
ผมจะเล่าเรื่อง Odoo Studio เท่าที่รู้
 
ปัจจุบัน Odoo เป็นโปรแกรม Cloud ERP (เมื่อก่อนไม่ใช่) มีการพัฒนาปรับปรุงตลอดเวลา และเป็น open source เปิดให้นักพัฒนาสามารถศึกษาและปรับแก้ไขเอาไปใช้งานตามต้องการได้ ขณะเดียวกันตัวโปรแกรมหลักเองก็มีการปรับปรุงออกเวอร์ชั่นใหม่ เพิ่มโมดูลหรือความสามารถที่เวอร์ชั่นเก่าไม่มี ปัญหาจึงเกิดขึ้น หากต้องการใช้ E-Commerce ที่มีในเวอร์ชั่นใหม่ แต่ติดตรงโค้ดที่เคยดัดแปลงใช้กับเวอร์ชั่นเดิมจะทำอย่างไร เพราะโค้ดเหล่านั้นขึ้นอยู่ฝีมือของโปรแกรมเมอร์ภายนอก ไม่สามารถรับประกันว่าจะสามารถอัพเกรดตามมาได้ เมื่อมี Odoo Studio ทำให้ควบคุมขอบเขตและวิธีการปรับแต่งว่าทำอะไรได้บ้าง ไม่ใช่เข้าไปแก้ไขโค้ดอิสระอย่างเดิม ที่สำคัญงาน customize ผ่าน Studio สามารถทำโดยผู้วางระบบไม่จำเป็นต้องอาศัยโปรแกรมเมอร์ และตัว Odoo เองก็สามารถช่วยดูแลการอัพเกรดเวอร์ชั่นได้
 
ที่จริงแล้วผมไม่ได้คิดการใหญ่ถึงระดับนั้น จุดเริ่มต้นมาจากผู้ใช้มีบริษัทในเครือจำนวนมาก และต้องเริ่มใช้งานพร้อมกันอย่างน้อย 4 บริษัท ในแง่ผู้ใช้มองว่าแต่ละบริษัทมีระบบงานเหมือนกัน แต่เมื่อลงไปเก็บรายละเอียดก็พบว่ามีส่วนที่แตกต่าง รวมถึงสไตล์การทำงานไม่เหมือนกัน จึงเป็นโจทย์บังคับให้ทำโปรแกรมเป็น "Multi-tenant" หรือ ERP as a Service นั่นเอง
 
MongoDB
 
กระบวนการพัฒนาโปรแกรมสมัยนั้นเริ่มต้นจากแนวคิดที่ว่า ต้องสำรวจและออกแบบทุกอย่างให้สมบูรณ์ที่สุด เพราะ database ที่นิยมใช้กันสมัยนั้นเป็น relational database ที่จำเป็นต้องกำหนด table, column และ key ที่เชื่อมโยงความสัมพันธ์ระหว่าง table ให้ชัดเจนตั้งแต่ก่อนเริ่มใช้งาน หากเก็บข้อมูลไปแล้ว หากแก้ไขเปลี่ยนแปลงภายหลัง เป็นเรื่องยากลำบาก มีข้อจำกัดทั้งในส่วนการดูแลเวอร์ชั่น database และโค้ดที่ทำงานกับ database นั้น ถึงแม้ว่ามีการใช้ ORM มาครอบเพื่อให้สามารถเขียนโค้ดจัดการได้สะดวกขึ้น แต่ก็ไม่ได้ออกแบบให้ใช้โค้ดเดียวกัน ทำงานกับ database ของบริษัทแต่ละแห่ง ที่มีโครงสร้างข้อมูลบางส่วนไม่เหมือนกัน
 
การเลือกใช้ database ที่รองรับโครงสร้างข้อมูลยืดหยุ่น ช่วยให้เปลี่ยนวงจรของการพัฒนาโดยสิ้นเชิง ออกแบบน้อย ๆ ทำออกมาเร็ว ๆ ทดลองใช้แล้วปรับปรุงเรื่อย ๆ ไม่ต้องกังวลออกแบบให้สมบูรณ์ตั้งแต่แรก ราคาที่ต้องจ่ายในการปรับเพิ่มรายละเอียดของข้อมูลที่เก็บใน database แต่ละครั้งเรียกว่าแทบไม่มีเลย ดังนั้นคุณสมบัติข้อนี้ของ database จึงเป็นเงื่อนไขแรกที่สำคัญ ที่ช่วยปลดล็อกกระบวนพัฒนาโปรแกรม
 
ก่อนที่จะเจอ MongoDB ผมมีโจทย์ที่ติดขัดตั้งแต่การออกแบบโปรแกรมสมัยก่อน เมื่อเจอผู้ใช้จากกิจการที่ไม่เหมือนกัน เช่น หากรองรับให้ใช้หลายสาขาได้ แล้วพวกที่มีสาขาเดียวจะต้องเห็นสาขาด้วยหรือไม่ ธุรกิจขายปลีก ขายส่ง และบริการ มีทางเดินเอกสารแตกต่างกัน จะต้องบังคับให้เดินเอกสารเหมือนกันหรือไม่ บางครั้งเจอเคสที่เกิดขึ้นไม่บ่อย การขายสินค้าที่ลูกค้าให้เปิดใบกำกับภาษีตามที่อยู่จดทะเบียน แต่ส่งสินค้าไปที่ไซต์งานอีกที่อยู่หนึ่งจะต้องออกแบบเผื่อให้ทำได้หรือไม่
 
จุดสำคัญของ MongoDB อยู่ที่การเก็บข้อมูลภายใน collection (เทียบเท่ากับ table ของ database อื่น) เป็น schemaless ไม่ต้องกำหนดโครงสร้างไว้ล่วงหน้า และไม่จำเป็นต้องมีโครงสร้างเหมือนกันทุกข้อมูล เรื่องนี้เป็นทุกข์มากตอนที่ไม่สามารถละทิ้งความเคยชินที่เคยคิดว่าฐานข้อมูลต้องเป็นตาราง และมีโครงสร้างเหมือนกัน ไม่งั้นจะมีปัญหาตามมามากมาย ไม่ว่าจะเป็นการตรวจสอบความถูกต้องของข้อมูล, การออกแบบรายงานจะทำอย่างไร เมื่อไม่แน่ใจในข้อมูลนั้นมีอะไรอยู่บ้าง ต้องใช้เวลาอยู่นานกว่าจะยอมสิโรราบ ละทิ้งหลักการออกแบบที่เคยทำ ไม่เอามาตั้งเป็นเงื่อนไข เช่นของเดิมเรื่องนี้ทำมาดีถ้าใช้ MongoDB จะต้องทำอย่างไร กลายเป็นเริ่มต้นคิดจาก MongoDB เป็นอย่างนี้ เราจะออกแบบโปรแกรมอย่างไรจึงดึงศักยภาพออกมาได้
 
เมื่อออกแบบให้เก็บข้อมูลใบกำกับภาษี ผมเริ่มต้นจากคิดถึงธุรกิจที่เล็กที่สุด ง่ายที่สุด เพื่อกำหนดเป็นรายละเอียดของข้อมูลที่น้อยที่สุดที่สามารถใช้เป็นใบกำกับภาษี ส่วนที่นอกเหนือจากนั้นเป็นตัวเลือกส่วนขยายที่สามารถปรับแต่งให้แตกต่างกันได้ เพราะข้อมูลภายใน collection ของแต่ละบริษัทที่ใช้งานก็ไม่จำเป็นต้องเหมือนกัน


 
Data API
 
คีย์สำคัญที่ทำให้โปรแกรมสามารถติดต่อกับ database และ collection หลากหลายได้ ขึ้นอยู่กับการออกแบบ Data API ตอนเริ่มแรกผมใช้ MongoDB ที่เป็น DaaS (Database as a Service) จาก mLab ซึ่งมี Data API ให้ใช้ด้วย ลดภาระงานพัฒนาส่วนของ backend database ไปแทบทั้งหมด
 
คุณสมบัติที่สำคัญของ mLab Data API อยู่ที่เป็น general purpose สามารถออกแบบให้ติดต่อกับ database และ collection ใด ๆ ก็ได้ ทำให้สามารถออกแบบโปรแกรมให้ทำงานในลักษณะของ database farm
 
ปัจจุบัน mLab หยุดให้บริการ โดน take over โดย MongoDB ไปแล้ว ผมอาศัยสเปคของ Data API มาพัฒนาต่อเพื่อเอาไปใช้กับ MongoDB Atlas อีกหนึ่ง ทำให้การอพยพ database จาก mLab ไป Atlas ในช่วงรอยต่อไม่มีปัญหาใด ๆ
 
Collection Name
 
การออกแบบโปรแกรมให้ใช้กับหลายแห่ง ผมใช้เทคนิคง่าย ๆ ตั้งชื่อ collection ให้มีรหัสของเจ้าของข้อมูลนำหน้า แล้วตามด้วยชื่อข้อมูล เช่น abc_docs เป็น collection ของบริษัท abc ที่ใช้เก็บข้อมูลเอกสาร และ xyz_docs ก็เป็นข้อมูลเอกสารของบริษัท xyz ดังนั้น
 
ข้อดีของวิธีนี้ ทำให้ลดจำนวน database ที่ต้องสร้างและเปิดใช้สำหรับกิจการขนาดเล็ก เพราะสามารถรวมใน database ส่วนกลางก่อน และอีกเหตุผลหนึ่งคือ ต้องการออกแบบให้บริษัทที่เป็นเครือเดียวกัน อยู่ใน database เดียวกัน
 
เมื่อโปรแกรมต้องการใช้ข้อมูล สามารถส่งคำสั่งค้นหา, เพิ่ม หรือแก้ไข โดยระบุรหัสบริษัท และชื่อข้อมูล ผ่าน Data API ที่ทำหน้าที่แปลงให้เป็นชื่อเต็ม collection และรู้ว่าเก็บอยู่ใน database ไหน
 
การตั้งชื่อแล้วติดต่อผ่าน Data API ทำให้มีความยืดหยุ่น สามารถออกแบบให้โยกย้าย database ภายหลังได้ เมื่อเริ่มต้นใช้งานยังไม่แน่ใจว่าจะมีปริมาณข้อมูลแค่ไหน ก็ให้อยู่ใน database รวมก่อน เปรียบเสมือนเป็นบ่อพักอนุบาล หากพบว่าใช้งานเยอะมีข้อมูลมากเติบโตเร็ว ก็สามารถแยกออกมาเป็น database ต่างหากภายหลังได้
 
Multi-cluster
 
ภายใน cluster หนึ่งสามารถมีหลาย database อยู่ด้วยกัน แต่ผมเลือกใช้วิธีแยกด้วยชื่อ collection แทน ดังนั้นการแยก database จึงมักทำพร้อมกับการสร้าง cluster ใหม่ด้วย
 
ประสิทธิภาพการทำงานของ database ใด ๆ ขึ้นอยู่กับสเปคของ cluster ว่ามี memory และ CPU เท่าไหร่ ยิ่ง database มีขนาดใหญ่ มีข้อมูลมากก็ต้องปรับขนาดของ memory และ CPU ให้ได้สัดส่วนตามกันด้วย
 
ดังที่กล่าวมาแล้ว ภายใน database อาจประกอบด้วยข้อมูลของหลายบริษัทรวมกันอยู่ ดังนั้นหากขนาดของ database นั้นใหญ่ เพราะมีจำนวนบริษัทมากเกินไป แทนที่จะปรับขยาย memory และ CPU เพิ่มขึ้น เราสามารถควบคุมขนาด database ไม่ให้ใหญ่เกินไป โดยการแยกบริษัทออกไปไว้ที่ cluster ใหม่แทน
 
ผลพลอยได้ของการแยก ช่วยกระจายความเสี่ยงเมื่อ cluster ใดมีปัญหาทำงานไม่ทันหรือหยุดทำงาน ก็จะมีผลเฉพาะบริษัทที่เก็บข้อมูลอยู่ใน cluster นั้นเท่านั้น
 
โดยปกติแล้วกิจการขนาดกลางที่มีคนใช้งานโปรแกรมพร้อมกันมากกว่า 10 คน มีความถี่ในการอ่านและเขียนข้อมูลมาก ผมจะแยก cluster ออกไปให้ใช้เฉพาะที่เดียว เพื่อไม่ให้มีกระทบกับผู้ใช้รายอื่น
 
Report Database
 
ภายใน cluster ของ MongoDB ประกอบด้วย 3 nodes รวมกันเป็น replica set หรือเทียบเท่ากับ server 3 ตัว ที่เก็บข้อมูลตรงกัน เปรียบเสมือน real-time backup ป้องกันมิให้ข้อมูลสูญหาย มี primary node เป็นด่านหน้า read & write รักษาข้อมูลต้นฉบับ และ secondary 2 nodes ที่เหลือคอยตามทำสำเนา
 
เราสามารออกแบบโปรแกรมส่วนที่ใช้งานอ่านข้อมูลจำนวนมาก เช่น รายงานต่าง ๆ ให้อ่านจาก secondary node แทน เพื่อลดภาระ primary node ที่ต้องรับหน้าที่บันทึกข้อมูล เปรียบเสมือนแยก operational database สำหรับใช้งานป้อนข้อมูล ออกจาก report database สำหรับใช้ทำรายงาน โดยอาศัยโครงสร้าง replica set

 
Report Cluster
 
ข้อจำกัดของการใช้ secondary node ใน replica set เป็น report อยู่ตรงที่ความละเอียดของข้อมูลเป็น transaction จึงเหมาะกับรายงานที่ใช้กับการตรวจสอบระดับรายละเอียด ที่เป็นช่วงเวลาแคบ ๆ เช่น รายงานประจำเดือน หากต้องรายงานวิเคราะห์ที่ต้องการตัวเลขที่เป็นยอดสรุประดับวัน หรือเดือน จะต้องทำ aggregation query ทุกครั้งที่ต้องการใช้ ซึ่งทำให้ฃ้าและกินแรง database
 
ในทางเทคนิครายงานที่ต้องเก็บตัวเลขสรุปและใช้ประจำ จะออกแบบให้คำนวณแล้วเก็บเป็น analytic model เอาไว้ก่อน แล้วรายงานอ่านข้อมูลนี้เอาไปใช้ได้ทันที โดยไม่ต้องเสียเวลาทำ aggregation ซ้ำซ้อน วิธีนี้เรียกว่าเป็นการทำ data pipeline แบบ ETL (Extract) อ่านข้อมูลจากต้นฉบับ (Transform) แปลงให้อยู่ในรูปแบบพร้อมใช้ทำรายงาน (Load) เก็บเอาไว้เป็นเหมือนข้อมูลอีกชุดหนึ่ง
 
เราสามารถอ่านข้อมูลจาก operational database ที่อยู่ใน cluster หนึ่ง แล้วแปลงเป็นข้อมูลสำหรับใช้รายงานเก็บไว้ใน report database อีก cluster หนึ่ง เพื่อไม่ให้การเรียกใช้รายงานวิเคราะห์รบกวน database ที่ใช้งานรูทีน
 
แสดงว่าข้อมูลของบริษัท ไม่จำเป็นต้องอยู่ใน database และ cluster เดียวกัน เพื่อให้ทำเช่นนี้ได้ ผมใช้วิธีออกแบบ Data API ให้สามารถตั้งค่า reroute collection ให้แยกไปใช้ cluster นอกอื่น ๆ ได้ โดยที่กลไกของรายงานอ้างถึงรหัสบริษัทเหมือนเดิมไม่ต้องรู้ว่า collection นั้นเก็บอยู่ที่ไหน


 
Data Model
 
เรื่องสุดท้ายที่จะเล่าให้ฟังถึงแนวคิดการออกแบบข้อมูล หลังจากที่ใคร่ครวญอยู่นาน ในที่สุดผมก็เลือกออกแบบให้ Transaction ทั้งหมดของ ERP เก็บอยู่ใน collection เดียวกันที่ชื่อว่า "doc"

 
ฐานข้อมูลที่จำเป็นสำหรับ ERP ประกอบด้วย collection ที่เป็น 3 หลัก (ขาดไม่ได้) และ 3 เสริม (ช่วยอำนวยความสะดวก)
 
"Config" collection
 
ผู้วางระบบใช้ตั้งค่า ออกแบบระบบเอกสาร กำหนดประเภทและรหัสเล่มเอกสาร คุณสมบัติของมัน เช่น ใช้เป็นใบกำกับภาษี, ใช้ตัดสต็อก, ใช้ลงบัญชีแยกประเภท ฯลฯ รวมทั้งกำหนดเงื่อนไขความสัมพันธ์กับเอกสารเล่มอื่น นอกจากยังใช้เก็บ Custom View และ Custom Edit ที่เป็นส่วนเสริมในการหน้าจอเมนู และหน้าจอเมนูเพิ่มเติม
 
"Link" collection
 
ผู้วางระบบใช้เก็บรายงานที่สร้างขึ้น สามารถเอามาใช้ประกอบเป็นเมนู และกำหนดหมวดหมู่และสิทธิ์การเรียกใช้รายงาน
 
"Doc" collection
 
เก็บข้อมูลเอกสารและ transaction ที่เกี่ยวข้องรวมอยู่ด้วยกัน การป้อนข้อมูลเข้าระบบจะมีรูปแบบเหมือนการบันทึกใส่เอกสาร ซึ่งเอกสารแต่ละเล่มอาจมีรายละเอียดไม่เหมือนกัน แต่จะมีฟิลด์สำคัญอย่างน้อยที่สุดได้แก่ ประเภท, เล่ม, เลขที่, วันที่
 
นอกจากเหนือจากนี้เป็น collection เสริม ได้แก่ "Who" ผู้เกี่ยวข้อง, "Which" สิ่งที่เกี่ยวข้อง (สินค้า) และ "What" เรื่องที่เกี่ยวข้อง มีเพื่อช่วยอำนวยความสะดวกตอนป้อนข้อมูล เช่น เมื่อใส่ชื่อลูกค้า ก็จะดึงเลขผู้เสียภาษี ที่อยู่ มาใส่ให้อัตโนมัติ และอีกเหตุผลที่สำคัญเพื่อไม่ให้โปรแกรมหลุดโลกเกินไปจนทีมวางระบบลำบากใจ
 
มีเพียงเท่านี้จริง ๆ จนไม่ต้องวาด Diagram เพราะไม่มี relation ที่โยงกันไปมา ผลที่ตามมาทำให้ทีมวางระบบไม่ต้องเรียนรู้ Data Model ถ้าอยากออกแบบรายงานภาษีขาย ก็เริ่มจากเขียน query กรองเอาเฉพาะเอกสารเล่มที่เป็นใบกำกับภาษี แล้วเลือกเอาฟิลด์ที่ต้องใช้มาแสดงให้เป็นรายงาน
 
ผมจะลองยกตัวอย่าง อธิบายว่ามีวิธีคิดหรือนิยามต่อคำเหล่านี้อย่างไร
 
บิลขาย และ ใบรับ 
ภายในข้อมูล Doc มีฟิลด์ "_type" ใช้สำหรับแยกประเภทเอกสาร โปรแกรมใช้ชื่อตรงนี้เพื่อกำหนดนิยามการทำงานเกี่ยวกับเอกสารตามประเภทนั้น ๆ ประเภท "บิลขาย" หมายถึงเอกสารที่มีธรรมชาติขายทางบัญชี คุณสมบัติย่อยที่สามารถกำหนดให้แตกต่างกันแต่ละหมวด จึงมีผลเป็นไปตามธรรมชาติขาย ผู้เกี่ยวข้องในบิลคือ ลูกค้า หรือลูกหนี้
 
หมวดไหนใช้คุมภาษี ก็จะเป็นรายการภาษีขาย 
หมวดไหนใช้คุมสต็อค ก็จะสร้างเป็นรายการออกสต็อค 
หมวดไหนใช้ลงบัญชี ก็จะสร้างเป็นรายการแยกประเภทอยู่ด้วยกัน
 
ยกตัวอย่าง ใบเสนอราคา เป็นบิลขายที่ไม่ใช้คุมอะไรเลย ใบส่งสินค้า/ใบกำกับภาษี ใช้คุมสต็อค,ภาษี และลูกหนี้ ในหมวดเดียวกัน
 
"ใบรับ" เป็นอนุพันธ์ของ "บิลขาย" มีธรรมชาติทางบัญชีเหมือนกัน ในทางเทคนิคไม่มีอะไรต่างกัน มักใช้กับหมวดบิลที่เป็นใบวางบิล หรือใบเสร็จรับเงิน เพื่อตัดหนี้กับบิลขาย ผมแยกออกมาเพื่อให้สอดคล้องกับการแยกเอกสาร ซื้อ-ขาย-จ่าย-รับ ของนักบัญชี
 
บิลซื้อ และ ใบจ่าย 
ธรรมชาติของ "บิลซื้อ" และ "ใบจ่าย" เกี่ยวข้องกับ เจ้าหนี้, ภาษีซื้อ และเข้าสต็อค
 
(ใบสำคัญ)แยกประเภท 
เป็นเอกสารที่ใช้บันทึกบัญชีแยกประเภทโดยตรง เดบิต เครดิต ส่วนใหญ๋จะใช้กับงานปรับปรุงบัญชี
 
ลูกหนี้ 
นิยามของลูกหนี้ คือ บิลขายที่ค้างชำระ query จาก Doc หาเอกสารที่เกี่ยวข้อง และมีเงื่อนไขค้างชำระ ชื่อลูกค้าในบิลเหล่านั้นคือลูกหนี้ ยอดที่ค้างชำระคือยอดหนี้
 
เจ้าหนี้ 
เจ้าหนี้ คือ บิลซื้อที่ค้างชำระ ใช้หลักคิดเดียวกับลูกหนี้
 
ลูกค้า 
สถานะความเป็นลูกค้าของกิจการ เป็นเรื่องชั่วคราวเช่นเดียวกับลูกหนี้ ดังนั้นจึงไม่ใช่เป็นการเก็บสะสมรายชื่อไว้ในฐานข้อมูล ชื่อที่เคยเป็นลูกค้าเมื่อสองปีที่แล้ว แต่ไม่เคยติดต่อค้าขายกันอีกเลยยังนับว่าเป็นลูกค้าหรือไม่
 
นิยามเรื่องลูกค้าของผมจะมีช่วงเวลาเข้ามาเกี่ยวข้องด้วย เช่น ลูกค้า 12 เดือนล่าสุด เอามาจากชื่อในเอกสารล่าสุดไม่เกิน 12 เดือนเท่านั้น ดังนั้นจำนวนลูกค้าของกิจการจึงอาจเปลี่ยนแปลงขึ้นลงได้
 
หากเข้าใจแนวคิดการกลั่นข้อมูลจากเอกสารแล้ว จะเห็นประโยชน์ความยืดหยุ่นจากมิติอื่น ๆ ของเอกสาร จัดกลุ่มลูกค้าออกเป็นประเภทย่อย ๆ ได้มากมาย เช่น ลูกค้าที่เคยเสนอราคาแต่ไม่เคยสั่งซื้อ
 
และเช่นเดียวกัน การช่วยอำนวยความสะดวกตอนป้อนข้อมูล เช่น แนะนำรายชื่อลูกค้า แล้วเอาเลขผู้เสียภาษี ที่อยู่มาใส่ให้ ก็สามารถเอามาจากประวัติในเอกสารนั้นเอง
 
สินค้า 
เรื่องของสินค้าสามารถออกแบบได้หลายวิธี ขึ้นอยู่กับธรรมชาติธุรกิจที่แตกต่างกัน กรณีที่ง่ายที่สุด คือ ธุรกิจที่ใช้ชื่อสินค้าตรงกับรายการในบิล สินค้าที่ซื้อและสินค้าที่ขายใช้ชื่อเหมือนกัน เช่น ธุรกิจที่ซื้อมาขายไป เราสามารถอนุโลมว่ารายการในบิล เป็นมิติเดียวกับสินค้าในสต็อค ใช้หลักคิดเหมือนกับลูกค้าได้ โปรแกรมสามารถใช้ประวัติจากบิลแนะนำรายชื่อสินค้า และราคาที่เคยขาย 
 
มีธุรกิจหลายประเภทที่สินค้าในมิติของสต็อค มิติขาย และมิติซื้อ ไม่ได้ง่าย ๆ ตรงไปตรงมา
 
ธุรกิจบางประเภทไม่สามารถเปิดบิลขายสินค้าโดยใช้ชื่อตามสต็อคได้ โดนบังคับให้ใช้ชื่อตามใบสั่งซื้อของลูกค้า
 
ธุรกิจบางประเภทชื่อซื้อกับขายไม่เท่ากัน ตอนซื้อมาจากหลายแหล่งผลิต แต่ตอนขายใช้ชื่อเดียวกัน
 
ธุรกิจบางประเภทหน่วยนับซื้อกับขายไม่ตรงกัน ตอนขายเอามารีแพ็คใหม่
 
ทุกธุรกิจที่ยกตัวอย่างมาข้างต้น สามารถทำได้โดยการวางระบบ ออกแบบทางเดินเอกสารในโปรแกรม
 
มีข้อด้อยที่ต้องระวัง การคำนวณยอดคงเหลือ เช่น สต็อคสินค้า ใช้วิธีคำนวณจากเอกสารที่เกี่ยวข้องทุกใบ เอา transaction สินค้าเข้าและออกมาบวกลบกันจนกลายเป็นยอดคงเหลือสุดท้าย ไม่เหมือนกับรายงานภาษีขายที่มีช่วงวันที่เป็นตัวคุมว่าไม่ต้องหาบิลย้อนหลังไปไกล วิธีนี้มีข้อดีที่ยืดหยุ่นปรับเงื่อนไขคำนวณได้ตามต้องการ ช่วยให้หายอดคงเหลือที่สโตร์ที่ต้องการ โดยเอาเอกสารที่บันทึกสินค้าชำรุดมารวมคำนวณด้วย แต่หากจำนวนเอกสารทั้งหมดที่สะสมเข้ามายิ่งนานวันมีมากขึ้นเรื่อย ๆ ก็จะทำให้การคำนวณช้าลงจนถึงวันที่ ข้อมูลมากเกินไปไม่สามารถประมวลผลได้
 
บทสรุป 
นึกถึงคำกล่าวของพี่คนหนึ่ง อะไรที่เวิร์ก มันจะง่าย ๆ โปรแกรมได้ถูกพิสูจน์ใช้งานและยืนระยะมาจนถึงวันนี้ ผมเชื่อว่าส่วนหนึ่งเกิดจากความพยายามคิดหาหนทางที่เรียบง่าย แต่เส้นทางที่ไร้ผู้ร่วมทางก็ทำให้เปลี่ยวล้า เมื่อถึงวาระที่รู้สึกว่าพอแล้วจึงเตรียมตัวสำหรับการพักวาง แนวคิดการใช้ออกแบบ ERP ที่ใช้ Database รุ่นใหม่น่าจะหาใครมาบอกเล่าไม่ง่ายนัก หรือบางทีอาจไม่เคยคิดว่าเป็นไปได้ มีหลายจุดที่รู้ว่ายังไม่ดี ภายหลังคิดวิธีที่ง่ายกว่าได้ แต่ต้องปล่อยวางไว้ เหมือนกับโปรแกรม ERP เก่าแก่ทั้งหลายที่มาไกลเกินกว่าจะกลับไปรื้อสร้างใหม่


บทความที่เกี่ยวข้อง
เว็บไซต์นี้มีการใช้งานคุกกี้ เพื่อเพิ่มประสิทธิภาพและประสบการณ์ที่ดีในการใช้งานเว็บไซต์ของท่าน ท่านสามารถอ่านรายละเอียดเพิ่มเติมได้ที่ นโยบายความเป็นส่วนตัว และ นโยบายคุกกี้
เปรียบเทียบสินค้า
0/4
ลบทั้งหมด
เปรียบเทียบ
Powered By MakeWebEasy Logo MakeWebEasy