PlusMagi's Blog By Pitt Phunsanit Database,Programming,SQL Server การสร้าง Table อ้างอิง (Reference Table ), ตารางอันตรภาคชั้น (Class Interval )แบบที่ 4 ลดรูป

การสร้าง Table อ้างอิง (Reference Table ), ตารางอันตรภาคชั้น (Class Interval )แบบที่ 4 ลดรูป

บทความนี้จะอธิบายถึงเทคนิคการตัด Column max_age ออกจากตารางเก็บช่วงอายุ เพื่อลดความซ้ำซ้อนของข้อมูล (Data Redundancy) โดยยังคงประสิทธิภาพในการ Query ไว้ครบถ้วน


เทคนิคการลดรูปตาราง: การจัดการช่วงอายุแบบ Dynamic โดยตัด max_age

ในการออกแบบระบบที่ต้องเก็บ “ช่วงอายุ” (Age Range) เช่น ขั้นตอนพัฒนาการของสมอง หรือเกณฑ์ภาษี หลายคนมักออกแบบตารางให้มีทั้ง min_age และ max_age ซึ่งมักจะเจอปัญหา “ข้อมูลขัดแย้งกันเอง” เช่น แถวที่หนึ่งจบที่ 8 แต่แถวที่สองเริ่มที่ 10 (เกิดช่องว่าง) หรือแถวที่สองเริ่มที่ 7 (เกิดช่วงทับซ้อน)

ทางเลือกที่ดีกว่าคือการเก็บเพียง min_age (จุดเริ่มต้น) เพียงอย่างเดียว


ปรับโครงสร้างตารางใหม่ (The Lean Structure)

จากเดิมที่เราต้องคีย์ข้อมูลสองฝั่ง เราจะเหลือเพียงการกำหนด “จุดเปลี่ยน” ของช่วงอายุเท่านั้น
Table: brain_development_stages

table_idstage_namemin_agekey_characteristic
1Childhood0Rapid Growth
3Adolescence9High Neuroplasticity
15Golden Age32Peak Stability

หมายเหตุ: table_id จะกระโดดอย่างไรก็ได้ เพราะเราจะยึด min_age เป็นหลักในการเรียงลำดับ


วิธีการ Query ข้อมูล (The Logic)

เมื่อเราไม่มี max_age ในตาราง เราจะใช้ความสามารถของ Window Function ใน SQL ที่ชื่อว่า LEAD () เพื่อ “มองข้ามไปยังแถวถัดไป” และนำค่า min_age ของแถวถัดไปมาลบออกด้วย 1 เพื่อสร้างเป็น end_range แบบเสมือน


SQL สำหรับสร้าง Dynamic Range

SELECT stage_name, min_age AS start_range, -- มองไปที่แถวถัดไป (เรียงตามอายุ) แล้วลบ 1 ถ้าไม่มีแถวถัดไปให้จบที่ 150 COALESCE (LEAD (min_age) OVER (ORDER BY min_age) - 1, 150) AS end_range, key_characteristic
FROM brain_development_stages;

ทำไมการลดรูปถึงดีกว่า ?

  • ป้องกัน Data Inconsistency
    คุณจะไม่เจอปัญหา “ช่วงอายุหลุด” หรือ “ช่วงอายุซ้อน” อีกต่อไป เพราะจุดจบของ Stage 1 จะถูกผูกติดกับจุดเริ่มของ Stage 2 โดยอัตโนมัติด้วย Code ไม่ใช่ด้วยการคีย์มือ
  • แก้ไขข้อมูลได้ง่าย (Single Point of Truth)
    หากต้องการเปลี่ยนให้วัยรุ่นเริ่มที่ 10 ปี (แทนที่ 9) คุณแก้แค่จุดเดียวในแถว Adolescence แล้วระบบจะคำนวณให้เองว่า Childhood ต้องไปจบที่ 9 ทันที
  • รองรับการแทรกข้อมูล (Scalability)
    ถ้าวันหนึ่งคุณอยากเพิ่ม Stage “Pre-Adolescence” ช่วงอายุ 7-8 ปี คุณเพียงแค่ INSERT ข้อมูลที่มี min_age = 7 เข้าไป โดยไม่ต้องไปไล่ Update max_age ของแถวเก่า ๆ ให้เหนื่อย

วิธีการนำไปใช้งานจริง (Search & Join)

เราสามารถใช้โครงสร้างนี้ไป Join กับตาราง Users เพื่อวิเคราะห์ข้อมูลตามช่วงอายุได้ทันทีโดยใช้ BETWEEN

WITH CalculatedStages AS (SELECT *, COALESCE (LEAD (min_age) OVER (ORDER BY min_age) - 1, 150) AS max_age FROM brain_development_stages) SELECT u.name, u.age, s.stage_name
FROM Users u
LEFT JOIN CalculatedStages s ON u.age BETWEEN s.min_age AND s.max_age;

สรุป

การตัด max_age ออก ไม่ใช่การทำให้ข้อมูลหายไป แต่เป็นการเปลี่ยนจากการเก็บข้อมูลที่ “ตายตัวและเสี่ยงต่อการผิดพลาด” ไปเป็นการเก็บข้อมูลแบบ “ความสัมพันธ์ต่อเนื่อง” ซึ่งเป็นแนวคิดที่เหมาะสมอย่างยิ่งสำหรับระบบที่ต้องการความแม่นยำสูงและจัดการง่ายในระยะยาวครับ


อ่านเพิ่มเติม

Exit mobile version