ข้ามไปยังเนื้อหา

IndexedDB คืออะไร?

IndexedDB คือ API ระดับต่ำที่ฝังอยู่ใน browser สมัยใหม่ทุกตัว ช่วยให้คุณจัดเก็บข้อมูลที่มีโครงสร้างจำนวนมากบนฝั่งไคลเอนต์ได้ รวมถึงไฟล์และ blob ต่างจาก localStorage และ sessionStorage ตรงที่ IndexedDB มีคุณสมบัติดังนี้

  • Asynchronous — ทุกการทำงานไม่บล็อกและใช้ event หรือ Promise
  • Transactional — การอ่านและเขียนเกิดขึ้นภายใน transaction จึงรับประกันความสอดคล้องของข้อมูลแม้เกิดข้อผิดพลาดกลางทาง
  • Object-oriented — จัดเก็บ object JavaScript ได้โดยตรง ไม่จำกัดแค่ string
  • Indexed — กำหนด index บน property ของ object ได้ และค้นหาได้อย่างมีประสิทธิภาพ
  • Large quota — browser มักอนุญาตให้ใช้พื้นที่หลายร้อย MB ถึง GB (ขึ้นอยู่กับการเจรจากับ browser ไม่ถูกจำกัดที่ 5–10 MB)
คุณสมบัติlocalStorage / sessionStorageIndexedDB
รูปแบบ APISynchronousAsynchronous (event / Promise)
ประเภทค่าstring เท่านั้นobject ที่มีโครงสร้าง, blob, ไฟล์
โควต้าพื้นที่~5–10 MBหลายร้อย MB ถึง GB
การค้นหาค้นหาด้วย key เท่านั้นkey + index บน property ใดก็ได้
Transactionไม่มีACID transaction เต็มรูปแบบ
เรียกใช้จาก workersessionStorage: ไม่ได้; localStorage: จำกัดใช้ได้เต็มที่ใน Web Worker

หลักการง่าย ๆ คือ ใช้ Web Storage สำหรับการตั้งค่าหรือค่าคอนฟิกขนาดเล็ก หันมาใช้ IndexedDB เมื่อต้องจัดเก็บเรคอร์ดที่มีโครงสร้าง ข้อมูลขนาดใหญ่ รองรับออฟไลน์ หรือค้นหานอกเหนือจาก key เดียว

database IndexedDB แต่ละตัวมีชื่อและหมายเลขเวอร์ชัน ภายใน database จะมี object store อย่างน้อยหนึ่งอัน คล้ายกับตารางใน database ทั่วไป แต่ละ object store เก็บ record ที่เป็น object JavaScript ที่ระบุตัวตนด้วย key

flowchart LR
  DB["Database
(name + version)"]
  OS1["Object Store
'users'"]
  OS2["Object Store
'posts'"]
  R1["Record
{id:1, name:'Ada'}"]
  R2["Record
{id:2, name:'Alan'}"]
  R3["Record
{id:1, title:'Hello'}"]
  DB --> OS1
  DB --> OS2
  OS1 --> R1
  OS1 --> R2
  OS2 --> R3
โครงสร้าง IndexedDB: database → object stores → records

ใช้ IndexedDB เมื่อมีเงื่อนไขข้อใดข้อหนึ่งต่อไปนี้

  • ต้องการจัดเก็บข้อมูล มากกว่าสองสามกิโลไบต์ ต่อ origin
  • ข้อมูลมี โครงสร้าง (object ที่มีหลาย field) และต้องการค้นหาหรือเรียงลำดับ
  • กำลังสร้างแอป offline-first หรือ PWA ที่ต้องการแคชการตอบสนองจากเครือข่ายหรือ sync queue
  • ต้องการจัดเก็บ ข้อมูลไบนารี เช่น รูปภาพ เสียง หรือ PDF blob
  • ต้องการเข้าถึง storage จาก Web Worker หรือ Service Worker

คงใช้ localStorage สำหรับ flag ง่าย ๆ การตั้งค่าธีม หรือ object JSON ขนาดเล็กที่ access แบบ synchronous ได้สะดวกและข้อมูลพอดีในไม่กี่ KB

โมดูลนี้จะพาคุณเรียนรู้ IndexedDB ตั้งแต่ต้นจนจบใน 5 บทเรียน

ลำดับบทเรียนสิ่งที่จะได้เรียนรู้
1IndexedDB คืออะไร? (บทเรียนนี้)แนวคิด โครงสร้าง และเวลาที่ควรใช้
2การเปิด databaseindexedDB.open, versioning, onupgradeneeded
3Object Stores และ Keysการสร้าง store, key path, auto-increment
4Transactionsread-only กับ read-write, การจัดการข้อผิดพลาด, การยกเลิก
5CRUD Operationsadd, put, get, getAll, delete, cursor

โค้ดด้านล่างเปิด database ยืนยันชื่อของตัวเอง แล้วลบทิ้งเพื่อไม่ให้เหลือร่องรอย

Browser Storage
ข้อใดคือความแตกต่างหลักระหว่าง IndexedDB กับ localStorage?
Object store ใน IndexedDB คืออะไร?
สถานการณ์ใดเหมาะกับการใช้ IndexedDB มากกว่า localStorage?