PlusMagi's Blog By Pitt Phunsanit Backend,Database 4. Query Language & Access Patterns (No SQL JOINs, Aggregation Pipelines, Querying by Access Patterns)

4. Query Language & Access Patterns (No SQL JOINs, Aggregation Pipelines, Querying by Access Patterns)

ในโลกของการพัฒนาซอฟต์แวร์ที่ขับเคลื่อนด้วยข้อมูล (Data-Driven Architecture) การจัดการกับข้อมูลขนาดใหญ่ (Big Data) และสถาปัตยกรรมแบบ Microservices ได้เปลี่ยนแปลงวิธีการที่เราเข้าถึงและประมวลผลข้อมูลอย่างสิ้นเชิง การพึ่งพาการ Join ตารางสัมพันธ์ (Relational Joins) จำนวนมากในการเรียกใช้ข้อมูลแต่ละครั้ง ไม่เพียงแต่เป็นคอขวดด้านประสิทธิภาพ (Performance Bottleneck) เท่านั้น แต่ยังทำให้แอปพลิเคชันมีความซับซ้อนในการบำรุงรักษาอย่างยิ่ง

หัวใจของการออกแบบ: จาก Tables สู่ Access Patterns

แนวคิดหลักของสถาปัตยกรรมสมัยใหม่คือการเปลี่ยนมุมมองจากการถามว่า “ฉันมีตารางอะไรบ้าง?” ไปสู่การถามว่า “ฉันจะอ่านข้อมูลชุดนี้อย่างไร?” การทำความเข้าใจ Access Patterns อย่างลึกซึ้งจึงเป็นสิ่งสำคัญที่สุดในการออกแบบ Schema โดยเราต้องระบุว่าแอปพลิเคชันส่วนใหญ่จะเรียกใช้ข้อมูลชุดใดร่วมกัน (เช่น เมื่อดู Order จะต้องดึง User Info และ Product List เสมอ)

เทคนิคการเพิ่มประสิทธิภาพ: Denormalization และ Embedding

เพื่อหลีกเลี่ยงการ Join ที่ซับซ้อน เราจึงใช้เทคนิค Denormalization หรือ Embedding ซึ่งหมายถึงการปรับโครงสร้างข้อมูลให้ข้อมูลที่เกี่ยวข้องถูกจัดเก็บไว้ในเอกสาร (Document) หรือแถว (Row) เดียวตั้งแต่แรกเริ่ม วิธีนี้ช่วยลดจำนวน Query และเพิ่มความเร็วในการอ่านข้อมูลได้อย่างมหาศาล โดยเฉพาะอย่างยิ่งเมื่อใช้ PostgreSQL ร่วมกับประเภทข้อมูลขั้นสูง เช่น JSONB หรือ Arrays

พลังของ Aggregation Pipelines ใน PostgreSQL

นอกจาก Denormalization แล้ว เครื่องมือที่ทรงพลังอย่าง Aggregation Pipelines คือกุญแจสำคัญในการประมวลผลข้อมูลหลายขั้นตอนภายในฐานข้อมูลเดียว แทนที่จะต้องดึงข้อมูลดิบจำนวนมหาศาลมาประมวลผลภายนอก (เช่น ใน Python หรือ Java) เราสามารถใช้ Common Table Expressions (CTEs) หรือ Window Functions ของ PostgreSQL เพื่อจำลองกระบวนการ Pipeline ได้อย่างมีประสิทธิภาพ

ตัวอย่างเช่น หากเราต้องการคำนวณราคาสุดท้ายของสินค้าหลังจากหักส่วนลดและเพิ่มภาษี เราสามารถใช้ CTEs เพื่อแบ่งขั้นตอนการคำนวณอย่างชัดเจน ทำให้ Query มีความอ่านง่ายและมีประสิทธิภาพสูงกว่าการเขียน Join ที่ซับซ้อนหลายชั้น

SQL

-- ตัวอย่างการใช้ CTEs (Common Table Expressions) เพื่อจำลอง Aggregation Pipeline ใน PostgreSQL
-- ขั้นตอนที่ 1: ดึงข้อมูลเริ่มต้น (Initial Data)
WITH raw_orders AS (
    SELECT 100 AS order_id, 'apple' AS item, 10.0 AS base_price
),
-- ขั้นตอนที่ 2: คำนวณราคาก่อนภาษี (Apply Discount/Calculation)
calculated_prices AS (
    SELECT order_id, item, base_price * 0.9 AS discounted_price
    FROM raw_orders
),
-- ขั้นตอนที่ 3: คำนวณราคาสุดท้ายพร้อมภาษี (Final Aggregation)
final_report AS (
    SELECT order_id, item, discounted_price * 1.07 AS final_price
    FROM calculated_prices
)
-- ผลลัพธ์สุดท้าย
SELECT * FROM final_report WHERE final_price > 100;

บทสรุป: การคิดแบบ Data Access First

การเป็น Senior Architect ในยุคปัจจุบันไม่ได้หมายถึงการเขียน SQL ที่ซับซ้อนที่สุด แต่หมายถึงการออกแบบ Schema ที่เหมาะสมกับรูปแบบการใช้งานจริง (Access Patterns) การใช้เทคนิค Denormalization, การฝังข้อมูล (Embedding), และการใช้คุณสมบัติขั้นสูงของ PostgreSQL อย่าง CTEs เพื่อสร้าง Aggregation Pipelines จะช่วยให้ระบบของเรามีประสิทธิภาพสูง ลดความซับซ้อนของ Query และรองรับการขยายตัวของข้อมูลขนาดใหญ่ได้อย่างยั่งยืน