ต้นไม้ปลอม: ใช้การเยื้องเพื่อทำ UI ที่เรียบง่ายกว่า
(ratfactor.com)ต้นไม้ปลอม: UI แบบง่ายด้วยการเยื้อง
- เมื่ออยากได้รายการแบบต้นไม้ใน UI การทำความสัมพันธ์พ่อแม่-ลูกมักต้องใช้แรงมากและต้องมีโครงสร้างข้อมูลที่ซับซ้อน
- ในฐานข้อมูลเชิงสัมพันธ์ สามารถใช้ recursive CTE (Common Table Expressions) เพื่อดึงข้อมูลโครงสร้างต้นไม้ได้
ข้อมูลจำเป็นต้องเป็นโครงสร้างต้นไม้จริงหรือไม่?
- ควรพิจารณาว่ารายการต่าง ๆ จำเป็นต้องมีความสัมพันธ์พ่อแม่-ลูกจริง ๆ หรือแค่ต้องดูเหมือนเป็นแบบนั้น
- หากไม่ต้องการความสัมพันธ์จริง ก็สามารถเก็บต้นไม้แบบง่าย ๆ ด้วยฟิลด์
id,sort,indent,name - วิธีนี้แสดงสิ่งที่เห็นบนหน้าจอตรง ๆ จึงทำให้อินเทอร์เฟซสำหรับเรนเดอร์และแก้ไขรายการง่ายขึ้นมาก
อีกตัวอย่างหนึ่งที่ใช้ "namespacing"
- ใน HissScript ถ้าชื่อรายการมีจุด (".") ก็จะตัดส่วนหน้าออกและเยื้องรายการ เพื่อทำฟีเจอร์ namespacing
- สำหรับตัวแก้ไขเกมและผู้เล่น namespacing เป็นเรื่องสำคัญ แต่ในความเป็นจริงมันก็เป็นเพียงชื่อธรรมดาเท่านั้น
- ผู้คนมักต้องการเพียงรูปลักษณ์ของโครงสร้างต้นไม้ มากกว่าตัวโครงสร้างจริง
โบนัส: tree-list
- เลียนแบบต้นไม้จริงโดยเก็บเส้นทางและข้อมูลไว้ในรายการแบบแบน แล้วจัดเรียงเส้นทางเพื่อเดินแบบ depth-first หรือ breadth-first
- รายการแบบแบนมักจัดการได้ง่ายกว่าและเหมาะกับคอมพิวเตอร์มากกว่า
อุปมาเชิงกายภาพ
- เวลาจัดสมุดภาพส่วนตัว สำหรับมนุษย์แล้ววิธีทำงานของการจัดกลุ่มนั้นชัดเจน แต่บนพื้นจริง ๆ ไม่มีกลไกทางกายภาพที่บังคับความสัมพันธ์แบบนั้นอยู่
ข้อควรระวัง: ไม่มีวิธีแก้ที่ใช้ได้กับทุกสถานการณ์
- ต้องเลือกใช้เทคนิคให้เหมาะกับสถานการณ์ และถ้าจำเป็นต้องใช้โครงสร้างต้นไม้จริง ก็ควรใช้ต้นไม้
- หากจำเป็นต้องรู้ความสัมพันธ์จริงระหว่างรายการ อย่าใช้การแฮ็กด้วยการเยื้องหรือการนับสัญลักษณ์ในสตริง
GN⁺ คิดเห็น:
- บทความนี้เสนอวิธีทำให้ส่วนติดต่อผู้ใช้ง่ายขึ้น โดยใช้การเยื้องที่เรียบง่ายในเชิงภาพแทนโครงสร้างต้นไม้ที่ซับซ้อนในการพัฒนาซอฟต์แวร์
- สำหรับนักพัฒนา นี่เป็นกลยุทธ์ที่มีประสิทธิภาพในการลดความซับซ้อนของโครงสร้างข้อมูล เพื่อประหยัดเวลาในการพัฒนาและทำให้การบำรุงรักษาง่ายขึ้น
- บทความนี้เน้นว่าโครงสร้างต้นไม้ไม่จำเป็นเสมอไป และบางครั้งเพียงโครงสร้างเชิงภาพที่ผู้ใช้คุ้นเคยก็เพียงพอแล้ว จึงมอบมุมมองใหม่ให้นักพัฒนาปรับปรุงประสบการณ์ผู้ใช้ได้
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
แนวทางแรกคือ 'adjacency list' ซึ่งถูกมองว่าเป็น "วิธีที่ถูกต้องเพียงวิธีเดียวอย่างชัดเจน"
แนวทางที่สองเป็น "วิธีที่ง่ายกว่ามาก" เป็นวิธีที่ไม่เคยเห็นมาก่อน และแม้จะมีข้อบกพร่องที่ชัดเจน แต่ในบางกรณีก็ชัดเจนเพียงพอ
แนวทางที่สามคือ 'namespacing' ซึ่งเรียกว่า 'materialized path'
ยังมีอีกวิธีหนึ่งในการแทนต้นไม้คือ 'nested sets' ซึ่งเป็นวิธีที่เป็นที่รู้จักกันดีในยุคที่มีการใช้งานฐานข้อมูลเชิงสัมพันธ์อย่างจริงจัง
Postgres มีชนิดข้อมูลและตัวดำเนินการค้นหาชื่อ 'ltree' ที่ช่วยให้จัดการโครงสร้างต้นไม้ได้อย่างเป็นธรรมชาติ ตัวอย่างเช่น สามารถใช้ 'ltree' สร้างตาราง แทรกข้อมูล แล้วค้นหาโครงสร้างต้นไม้ด้วยคำสั่งค้นหาแบบง่ายได้
ค่าภายในโครงสร้างมักเป็นลำดับชั้นของข้อมูล ไม่ใช่ต้นไม้ที่แสดงผลอยู่เสมอ คุณอาจต้องการวนดูข้อมูล แสดงความสัมพันธ์ หรือจัดเรียงใหม่ การเก็บข้อมูลเชิงภาพไว้ในโครงสร้างข้อมูลภายในฐานข้อมูลอาจเป็นมุมมองระยะสั้นเกินไป
เคยก่อตั้งบริษัทที่ทำงานกับข้อมูลแบบต้นไม้ สามารถแปลงโครงสร้างต้นไม้เป็นรายการแบบย่อหน้าเยื้องได้ในเวลา O(n) นี่เคยเป็นหนึ่งในคำถามสัมภาษณ์ และในฐานข้อมูล SQL ก็มีหลายวิธีในการดึงบางส่วนของต้นไม้มารวดเร็วและเรนเดอร์ได้ โดยไม่ต้องใช้ recursive query
วิธีหนึ่งในการดึงข้อมูลโครงสร้างต้นไม้จากฐานข้อมูลเชิงสัมพันธ์ด้วย SQL คือการเขียน recursive CTE (Common Table Expressions) จริง ๆ แล้ว CTE สนุกดี และเมื่อคุ้นเคยแล้วก็ไม่มีอะไรให้น่ากลัว
จากประสบการณ์ คนเรามักไม่ได้ต้องการต้นไม้จริง ๆ แต่แค่ต้องการหน้าตาแบบต้นไม้ HN กับ Reddit ต่างกันในจุดนี้ ใน HN ความเห็นลูกจะเป็นพี่น้องลำดับถัดไปของความเห็นแม่ โดยเพิ่มการเยื้องอีกหนึ่งระดับจากความเห็นแม่เพื่อเลียนแบบหน้าตาแบบต้นไม้ ขณะที่ใน Reddit ความเห็นลูกจะถูกซ้อนอยู่ภายในความเห็นแม่จริง ๆ
แนวคิดหลักของบทความคือการใช้โครงสร้างที่เหมาะกับปัญหา แต่การเล่าเรื่องยังมีข้อบกพร่อง ไม่จำเป็นต้องใช้ CTE เพื่อดึงต้นไม้จากฐานข้อมูล และสามารถดึงรายการแบบแบนมาประกอบเป็นต้นไม้ในเครื่องได้ นอกจากนี้ หากเป็นต้นไม้ที่ใหญ่พอ การย้ายกิ่งหรือเปลี่ยนความลึกอาจมีต้นทุนเชิงเส้น
เมื่อต้องอธิบายอนุกรมวิธานหรือโครงสร้างลำดับชั้นอื่น ๆ ได้เรียนรู้วิธีที่ง่ายและรวดเร็วโดยใช้ระบบไฟล์ในเครื่อง ใช้คำสั่ง 'mkdir' และ 'tree' แล้วคัดลอกไปวางในอีเมล Slack, pastebin ฯลฯ
ถ้าต้องการแค่บันทึก/โหลดข้อมูล การ serialize ข้อมูลเป็นสตริงในรูปแบบที่ต้องการ (เช่น JSON) อาจเป็นทางออกที่ง่ายกว่า การใช้สัญลักษณ์จุดมีความคล้ายกับวิธีที่ Dendron ซึ่งเป็นส่วนขยายของ VsCode ใช้จัดการลำดับชั้นของชื่อ
หลายปีก่อนได้ข้อสรุปคล้ายกันเกี่ยวกับ OpenGL: ไม่จำเป็นต้องเรนเดอร์โลกของวัตถุ 3D แบบลำดับชั้น แค่เรนเดอร์รายการสามเหลี่ยมที่จัดเรียงแล้วก็พอ ซึ่งทำให้การเพิ่มประสิทธิภาพหลายอย่างง่ายมาก