ในโลกของการพัฒนาซอฟต์แวร์และระบบข้อมูลขนาดใหญ่ เรามักเผชิญกับความผันผวนของข้อมูล (Data Volatility) และความซับซ้อนของระบบที่ยากจะคาดเดา การที่เราพยายามควบคุมทุกตัวแปร ตั้งแต่ความถูกต้องของข้อมูลต้นทางไปจนถึงผลลัพธ์สุดท้ายที่ผู้ใช้งานจะเห็น มักนำมาซึ่งความเหนื่อยล้าทางความคิด (Cognitive Overload) และการเขียนโค้ดที่ซับซ้อนเกินความจำเป็น
แก่นแท้ของแนวคิด ‘Outcome Independence’ คือการที่เราต้องแยกแยะอย่างชัดเจนระหว่าง สิ่งที่เรารควบคุมได้ (Process/Effort) และ สิ่งที่อยู่นอกเหนือการควบคุม (Outcome/Result) ในฐานะ System Architect เราต้องมุ่งเน้นพลังงานทั้งหมดไปที่การออกแบบกระบวนการ (Process) ของเราให้ดีที่สุด เพราะนั่นคือขอบเขตอำนาจที่แท้จริงของเรา
💡 หลักการ Process vs. Outcome ในสถาปัตยกรรมข้อมูล
ในทาง PostgreSQL หรือระบบฐานข้อมูลใดๆ Process คือชุดคำสั่ง (Query Logic, Function Definition, Transaction Flow) ที่เราเขียนขึ้น ซึ่งเราสามารถควบคุมความสมบูรณ์และความมีประสิทธิภาพได้ 100% ส่วน Outcome คือชุดข้อมูลที่ส่งกลับมา (Result Set) ซึ่งผลลัพธ์นี้ขึ้นอยู่กับปัจจัยภายนอก เช่น ข้อมูลที่ถูกแทรกเข้ามาโดยระบบอื่น, การเปลี่ยนแปลงของ Trigger, หรือแม้แต่การที่ข้อมูลต้นทางมีค่า NULL ที่เราไม่ได้คาดการณ์
การปล่อยวางผลลัพธ์จึงไม่ใช่การยอมแพ้ แต่คือการยอมรับว่าแม้เราจะเขียน Query ที่สมบูรณ์แบบแค่ไหน แต่ถ้าข้อมูลต้นทาง (Source Data) มีปัญหา เราก็ต้องออกแบบระบบที่แข็งแกร่งพอที่จะรับมือกับความไม่สมบูรณ์นั้นได้
⚙️ การมุ่งเน้นที่ Process ด้วย PostgreSQL CTE
เราสามารถใช้ Common Table Expressions (CTE) ใน PostgreSQL เพื่อจำลองการมุ่งเน้นที่กระบวนการ (Process) อย่างชัดเจน CTE บังคับให้เรากำหนดขั้นตอนการประมวลผลข้อมูลอย่างเป็นลำดับขั้น ซึ่งเป็นสิ่งที่เรารควบคุมได้ทั้งหมด โดยไม่จำเป็นต้องกังวลว่าข้อมูลจะถูกเปลี่ยนแปลงอย่างไรในขั้นตอนถัดไป
ตัวอย่างนี้แสดงถึงการกำหนด Process ที่ชัดเจน: เรากรองและแปลงข้อมูล (Process) ก่อนที่จะนำไปใช้ในการคำนวณขั้นสุดท้าย (Outcome) ซึ่งเป็นวิธีที่ช่วยให้เรามั่นใจในความถูกต้องของขั้นตอนการทำงานของเรา:
SQL
WITH filtered_process AS ( -- นี่คือ Process ที่เราควบคุมได้ 100% SELECT id, name, CAST(value AS INTEGER) AS numeric_value FROM input_data WHERE name IN ('apple', 'banana', 'orange') ) SELECT id, name, numeric_value FROM filtered_process WHERE numeric_value > 1;
ในโค้ดข้างต้น filtered_process คือขอบเขตที่เราควบคุมได้ เราได้กำหนดเงื่อนไขการกรองและแปลงข้อมูลอย่างแม่นยำแล้ว การที่เรามั่นใจในความถูกต้องของ CTE นี้ คือการที่เรากำลังทำหน้าที่ของเราให้ดีที่สุด
✅ บทสรุป: ความสงบในโค้ดที่สมบูรณ์แบบ
การปล่อยวางผลลัพธ์ในเชิงสถาปัตยกรรมข้อมูล ไม่ได้หมายถึงการเขียนโค้ดที่หละหลวม แต่หมายถึงการเขียนโค้ดที่ แข็งแกร่งพอที่จะรับมือกับความไม่แน่นอน (Resilience) เราต้องมั่นใจว่า Process ของเราสมบูรณ์ที่สุด ใช้ Transaction Management, ใช้ CTEs เพื่อแบ่งขั้นตอนการทำงาน และใช้ Type Casting อย่างระมัดระวัง เพื่อให้มั่นใจว่าถึงแม้ Outcome จะไม่เป็นไปตามที่คาดหวัง แต่ระบบของเราก็ยังคงทำงานได้อย่างสง่างามและสามารถตรวจสอบย้อนกลับได้