วัน: 18 เมษายน 2020

จิ๊กซอว์ (Jigsaw puzzle)จิ๊กซอว์ (Jigsaw puzzle)

ในโลกของระบบฐานข้อมูล การจัดการข้อมูลที่ซับซ้อนและมีความสัมพันธ์กันเป็นหัวใจสำคัญของงานวิศวกรรมซอฟต์แวร์ การเปรียบเทียบการแก้ปัญหาเหล่านี้กับการต่อจิ๊กซอว์ (Jigsaw puzzle) ช่วยให้เราเห็นภาพว่า PostgreSQL สามารถเชื่อมโยงชิ้นส่วนข้อมูลที่ดูเหมือนกระจัดกระจายให้กลายเป็นภาพรวมที่สมบูรณ์ได้อย่างไร

Jigsaw Puzzle ในมุมมองของ PostgreSQL

ในทางเทคนิค จิ๊กซอว์แต่ละชิ้นสามารถถูกมองว่าเป็น ‘ระเบียน’ (Record) หรือ ‘แถว’ (Row) ในตารางฐานข้อมูลแต่ละชิ้นส่วนของภาพรวมคือ ‘ชุดข้อมูล’ (Dataset) ทั้งหมด การเชื่อมโยงชิ้นส่วนเหล่านี้เข้าด้วยกันเพื่อหาคำตอบที่สมบูรณ์ คือการใช้คำสั่ง JOIN หรือการใช้ WITH RECURSIVE ใน PostgreSQL

การสร้างแบบจำลองชิ้นส่วน (Modeling the Pieces)

เราจะสมมติว่าเรามีตารางชื่อ puzzle_pieces ที่เก็บข้อมูลของชิ้นส่วนจิ๊กซอว์แต่ละชิ้น โดยแต่ละชิ้นส่วนจะมีรหัส (piece_id) และมีข้อมูลที่ระบุว่าชิ้นส่วนนี้ต้องเชื่อมต่อกับชิ้นส่วนใดเพื่อสร้างลำดับถัดไป (next_piece_id) นี่คือการสร้างความสัมพันธ์แบบ One-to-Many

SQL

CREATE TABLE puzzle_pieces (\n    piece_id TEXT PRIMARY KEY, \n    piece_data TEXT NOT NULL, \n    next_piece_id TEXT \n);\n\nINSERT INTO puzzle_pieces (piece_id, piece_data, next_piece_id) VALUES\n('A', 'ชิ้นส่วนเริ่มต้น', 'B'),\n('B', 'ชิ้นส่วนกลาง', 'C'),\n('C', 'ชิ้นส่วนสุดท้าย', NULL);

การเชื่อมโยงชิ้นส่วนด้วย JOIN

การหาลำดับการต่อจิ๊กซอว์ที่ถูกต้องก็คือการค้นหาเส้นทาง (Path) ของข้อมูลที่เชื่อมโยงกันอย่างถูกต้องในฐานข้อมูล เราใช้ JOIN เพื่อจำลองการเชื่อมต่อนี้:

SQL

SELECT \n    p1.piece_data AS piece_1, \n    p2.piece_data AS piece_2 \nFROM \n    puzzle_pieces p1 \nJOIN \n    puzzle_pieces p2 ON p1.next_piece_id = p2.piece_id \nWHERE \n    p1.piece_id = 'A';

คำสั่งนี้จะดึงข้อมูลของชิ้นส่วน ‘A’ และเชื่อมมันเข้ากับชิ้นส่วนที่รหัส next_piece_id ของ ‘A’ ชี้ไป (คือ ‘B’) ทำให้เราได้เห็นการเชื่อมต่อเป็นคู่ๆ อย่างเป็นระบบ

การแก้ปัญหาเชิงลึกด้วย Recursive CTE

หากจิ๊กซอว์มีความซับซ้อนและมีหลายระดับการเชื่อมต่อ (เช่น การหาลำดับทั้งหมดตั้งแต่ A ไปจนถึง C) เราจะใช้ WITH RECURSIVE ซึ่งเป็นเครื่องมือที่ทรงพลังที่สุดในการจำลองการต่อจิ๊กซอว์ที่ซับซ้อนใน PostgreSQL

SQL

WITH RECURSIVE puzzle_solution AS (\n    SELECT \n        piece_id, \n        piece_data, \n        next_piece_id, \n        1 AS step \n    FROM \n        puzzle_pieces \n    WHERE \n        piece_id = 'A' \n    UNION ALL \n    SELECT \n        p.piece_id, \n        p.piece_data, \n        p.next_piece_id, \n        s.step + 1 \n    FROM \n        puzzle_pieces p \nJOIN \n        puzzle_solution s ON p.piece_id = s.next_piece_id \n) \nSELECT \n    step, \n    piece_data \nFROM \n    puzzle_solution \nORDER BY \n    step;

WITH RECURSIVE จะทำหน้าที่วนซ้ำ (Iteratively) เหมือนการต่อจิ๊กซอว์ทีละชิ้น จนกว่าจะถึงชิ้นส่วนสุดท้ายที่ไม่มี next_piece_id ทำให้เราได้ลำดับการต่อที่สมบูรณ์และเป็นระเบียบ

บทสรุป

ดังนั้น การมองจิ๊กซอว์เป็นปัญหาเชิงความสัมพันธ์ (Relational Problem) ทำให้เราเห็นว่า PostgreSQL ไม่ได้เป็นเพียงแค่ที่เก็บข้อมูล แต่เป็นเครื่องมือในการ ‘แก้ปัญหา’ ด้วยการใช้ JOIN และ WITH RECURSIVE เพื่อเชื่อมโยงชิ้นส่วนข้อมูลที่กระจัดกระจายให้กลายเป็นภาพรวมที่สมบูรณ์และมีประสิทธิภาพสูงสุด