นักพัฒนาถกเถียง SQLite กับ PostgreSQL สำหรับแอป Local-First ขณะที่โซลูชัน Sync ใหม่เริ่มปรากฏ

ทีมชุมชน BigGo
นักพัฒนาถกเถียง SQLite กับ PostgreSQL สำหรับแอป Local-First ขณะที่โซลูชัน Sync ใหม่เริ่มปรากฏ

ชุมชนนักพัฒนาแอปพลิเคชัน local-first กำลังหารือกันอย่างกระตือรือร้นเกี่ยวกับโซลูชันฐานข้อมูลที่ดีที่สุดสำหรับการสร้างแอปที่ตอบสนองและใช้งานได้แบบออฟไลน์ การสนทนานี้มีความเข้มข้นมากขึ้นหลังจากที่นักพัฒนาคนหนึ่งได้แชร์รายงานประสบการณ์โดยละเอียดเปรียบเทียบแนวทางต่างๆ ในการสร้าง sync engine ด้วย SQLite และ PostgreSQL

Electric และ PGlite แสดงศักยภาพแต่เผชิญปัญหาด้าน Scalability

นักพัฒนาหลายคนได้ทดลองใช้ Electric SQL ร่วมกับ PGlite ซึ่งเป็นการใช้งาน PostgreSQL แบบ WebAssembly ที่ทำงานในเบราว์เซอร์ แม้ว่าการรวมกันนี้จะให้ข้อได้เปรียบในการใช้ database engine เดียวกันทั้งในเครื่องและบนเซิร์ฟเวอร์ แต่สมาชิกในชุมชนได้รายงานปัญหาด้านประสิทธิภาพที่สำคัญ ปัญหาที่เด่นชัดที่สุดคือเวลาเริ่มต้นที่เกินหนึ่งนาทีเมื่อฐานข้อมูลมีขนาดใหญ่ขึ้น ซึ่งเกิดจากการขาดฟีเจอร์ compaction หลักๆ นอกจากนี้ยังมีปัญหา memory leak และความไม่เสถียรในการทำงานพร้อมกันเมื่อฐานข้อมูลมีขนาดใหญ่ขึ้น

น่าสนใจที่ผู้มีส่วนร่วมหลักในโปรเจค Electric ได้ยอมรับข้อจำกัดเหล่านี้และเปิดเผยว่าปัญหาเหล่านี้เป็นแรงจูงใจในการสร้าง TanStack DB ซึ่งเป็น client-side datastore ใหม่ที่พัฒนาด้วย JavaScript ที่ออกแบบมาให้เป็น sync native และไม่ขึ้นกับ backend

ปัญหาด้านประสิทธิภาพที่มีการรายงานทั่วไป:

  • เวลาเริ่มต้นของ PGlite: มากกว่า 1 นาทีสำหรับฐานข้อมูลขนาดใหญ่
  • การรั่วไหลของหน่วยความจำ: เกิดขึ้นเมื่อมีการร้องขอ LISTEN พร้อมกันเพิ่มขึ้น
  • ปัญหาความเสถียร: ในโหมดผู้ใช้เดียวเมื่อขนาดฐานข้อมูลเพิ่มขึ้น
  • การบีบอัดข้อมูลที่หายไป: นำไปสู่การขยายตัวของฐานข้อมูลเมื่อเวลาผ่านไป
  • ค่าใช้จ่ายเพิ่มเติมของ WASM: ประสิทธิภาพการสืบค้นที่ช้ากว่าการใช้งานแบบ native

SQLite ได้รับความนิยมสำหรับแอปพลิเคชันผู้ใช้เดียว

การอภิปรายได้เน้นย้ำถึงความนิยมที่เพิ่มขึ้นของ SQLite สำหรับแอปพลิเคชัน local-first โดยเฉพาะในสถานการณ์ผู้ใช้เดียวเช่นแอปจดบันทึก นักพัฒนาพบว่าธรรมชาติที่เบาและเสถียรของ SQLite ทำให้เหมาะสำหรับแอปพลิเคชันในเบราว์เซอร์ที่ใช้การใช้งาน WebAssembly เช่น wa-sqlite ความท้าทายหลักของ SQLite คือการใช้งาน reactivity เนื่องจากขาดฟังก์ชัน LISTEN ของ PostgreSQL สำหรับการแจ้งเตือนการเปลี่ยนแปลงแบบเรียลไทม์

สมาชิกในชุมชนได้แชร์วิธีแก้ปัญหาที่สร้างสรรค์ รวมถึงการใช้ database trigger เพื่อบันทึกการเปลี่ยนแปลงและ Broadcast Channel API เพื่อแจ้งเตือนส่วนต่างๆ ของแอปพลิเคชันเกี่ยวกับการอัปเดต แนวทางนี้ได้พิสูจน์ประสิทธิภาพในการสร้างแอปพลิเคชันที่ตอบสนองอย่างสมบูรณ์และรู้สึกเร็วเท่ากับโซลูชันใน memory

โซลูชัน Polling แบบง่ายพิสูจน์ประสิทธิภาพสำหรับหลายกรณีการใช้งาน

แนวโน้มที่น่าสนใจในการอภิปรายของชุมชนคือการตระหนักว่า sync engine ที่ซับซ้อนอาจเกินความจำเป็นสำหรับแอปพลิเคชันหลายตัว สำหรับแอปผู้ใช้เดียวที่มีการเชื่อมต่ออินเทอร์เน็ตที่เชื่อถือได้ นักพัฒนาพบความสำเร็จด้วยระบบ polling แบบ timestamp ง่ายๆ ที่ดึงการเปลี่ยนแปลงทุกไม่กี่วินาที แนวทางนี้ใช้ JSON request ที่ตรงไปตรงมาและสามารถใช้งานได้ด้วยโค้ดเพียงเล็กน้อยในขณะที่ยังคงให้ประสบการณ์ผู้ใช้ที่ยอดเยี่ยม

การสร้าง sync engine อาจเป็นประสบการณ์การเรียนรู้ที่ดี แต่สำหรับซอฟต์แวร์ที่ใช้ในการผลิต จะดีกว่าหากเลือกใช้สิ่งที่เผชิญและแก้ไขปัญหาแปลกๆ ทั้งหมดที่เกิดขึ้นเมื่อสร้าง sync engine และ persistent storage บนเบราว์เซอร์แล้ว

โซลูชันฐานข้อมูล Local-First หลักที่กล่าวถึง:

โซลูชัน เครื่องมือฐานข้อมูล คุณสมบัติหลัก เหมาะสำหรับ
Electric + PGlite PostgreSQL (WASM) การซิงค์แบบละเอียด, รองรับ LISTEN แอปพลิเคชันที่ทำงานร่วมกันหลายผู้ใช้
TanStack DB ใช้พื้นฐาน JavaScript ซิงค์ดั้งเดิม, ไม่ขึ้นกับแบ็กเอนด์ ที่เก็บข้อมูลฝั่งไคลเอนต์ทั่วไป
Evolu SQLite การเข้ารหัสแบบ E2E, เครื่องมือซิงค์ แอปพลิเคชันที่เน้นความเป็นส่วนตัว
wa-sqlite SQLite (WASM) น้ำหนักเบา, เสถียร แอปพลิเคชันผู้ใช้เดียว
Custom polling ใดๆ การซิงค์แบบง่ายตาม timestamp ความต้องการซิงค์ที่ซับซ้อนน้อย

โซลูชันทางเลือกและเครื่องมือเฉพาะทาง

ชุมชนยังได้เน้นย้ำถึงโซลูชันสำเร็จรูปหลายตัวสำหรับกรณีการใช้งานที่แตกต่างกัน Evolu เสนอการ sync แบบ SQLite พร้อมการเข้ารหัสแบบ end-to-end ในขณะที่เครื่องมือเช่น Reflect ได้ใช้งานแนวทางที่คล้ายกันในการผลิตอย่างสำเร็จ นักพัฒนาบางคนที่ทำงานกับแอปพลิเคชันเฉพาะทาง เช่น ระบบ smart home ที่ใช้ CRDT ผ่าน CAN bus และ Bluetooth กำลังสร้างโซลูชันแบบกำหนดเองตั้งแต่เริ่มต้นเนื่องจากข้อจำกัดของแพลตฟอร์มที่เป็นเอกลักษณ์

การอภิปรายเผยให้เห็นระบบนิเวศที่กำลังเติบโตซึ่งนักพัฒนาสามารถเลือกจากเครื่องมือที่ซับซ้อนมากขึ้นหรือสร้างโซลูชันแบบกำหนดเองที่เหมาะกับความต้องการเฉพาะของพวกเขา ข้อมูลเชิงลึกหลักที่เกิดขึ้นจากชุมชนคือการเลือก sync engine ควรขับเคลื่อนด้วยข้อจำกัดของแอปพลิเคชันมากกว่าความชอบทางเทคนิค โดยปัจจัยเช่น จำนวนผู้ใช้พร้อมกัน ความถี่ในการเขียน และรูปแบบการใช้งานออฟไลน์เป็นตัวกำหนดแนวทางที่เหมาะสม

อ้างอิง: Lessons learned from building a sync-engine and reactivity system with SQLite