تعد IndexedDB إحدى إمكانيات التخزين المقدمة في المتصفحات على مر السنين. إليك مقدمة إلى IndexedDB ، قاعدة بيانات الويب التي تدعمها جميع المتصفحات الحديثة
- مقدمة إلى قاعدة البيانات المفهرسة
- إنشاء قاعدة بيانات مفهرسة
- إضافة البيانات إلى المتجر
- الحصول على البيانات من متجر
- حذف البيانات من قاعدة البيانات المفهرسة
- الترحيل من الإصدار السابق لقاعدة البيانات
- مفاتيح فريدة
- الحذف من IndexedDB
- هناك المزيد!
مقدمة إلى قاعدة البيانات المفهرسة
تعد IndexedDB إحدى إمكانيات التخزين المقدمة في المتصفحات على مر السنين. إنه مخزن مفتاح / قيمة (قاعدة بيانات noSQL) يعتبر كذلكالحل النهائي لتخزين البيانات في المتصفحات.
إنها واجهة برمجة تطبيقات غير متزامنة ، مما يعني أن إجراء عمليات مكلفة لن يمنع مؤشر ترابط واجهة المستخدم الذي يوفر تجربة قذرة للمستخدمين. يمكنه تخزين كمية غير محددة من البيانات ، على الرغم من أنه بمجرد تجاوز حد معين ، يُطلب من المستخدم إعطاء الموقع حدودًا أعلى.
إنهمدعوم على جميع المتصفحات الحديثة.
وهو يدعم المعاملات وإصدار الإصدارات ويعطي أداءً جيدًا.
داخل المتصفح يمكننا أيضًا استخدام:
- بسكويت: يمكن أن تستضيف كمية صغيرة جدًا من السلاسل
- تخزين الويب(أو DOM Storage) ، وهو مصطلح يعرّف عادةً localStorage و sessionStorage ، وهما مخزنان للمفتاح / القيمة. جلسة التخزين ، لا تحتفظ بالبيانات ، والتي يتم مسحها عند انتهاء الجلسة ، بينما يحتفظ localStorage بالبيانات عبر الجلسات
من عيوب التخزين المحلي / التخزين في الجلسة أن يتم تحديده بحجم صغير (وغير متسق) ، حيث يوفر تنفيذ المتصفحات مساحة تتراوح من 2 ميجابايت إلى 10 ميجابايت لكل موقع.
في الماضي كان لدينا أيضاSQL الويب، التفاف حول SQLite ، ولكن هذا الآنإهمالوغير مدعوم في بعض المتصفحات الحديثة ، لم يكن أبدًا معيارًا معترفًا به ولذلك لا ينبغي استخدامه ، على الرغم من أن 83٪ من المستخدمين لديهم هذه التقنية على أجهزتهموفقًا لـ Can I Use.
بينما يمكنك إنشاء قواعد بيانات متعددة تقنيًا لكل موقع ، فإنك عمومًاإنشاء قاعدة بيانات واحدة، وداخل قاعدة البيانات يمكنك إنشاءمخازن كائن متعددة.
قاعدة البيانات هيخاص بالمجال، لذلك لا يمكن لأي موقع آخر الوصول إلى موقع ويب آخر لمتاجر IndexedDB.
يحتوي كل متجر عادة على مجموعة منأشياء، التي يمكن أن تكون
- سلاسل
- أعداد
- شاء
- المصفوفات
- تواريخ
على سبيل المثال ، قد يكون لديك متجر يحتوي على منشورات وآخر يحتوي على تعليقات.
يحتوي المتجر على عدد من العناصر التي لها مفتاح فريد ، والذي يمثل الطريقة التي يمكن من خلالها التعرف على الكائن.
يمكنك تغيير تلك المتاجر باستخدام المعاملات ، عن طريق إجراء عمليات الإضافة والتعديل والحذف ، والتكرار على العناصر التي تحتوي عليها.
منذ قدوموعودفي ES6 ، والانتقال اللاحق لواجهات برمجة التطبيقات إلى استخدام الوعود ، تبدو واجهة برمجة تطبيقات IndexedDB قليلاًمدرسة قديمة.
بينما لا يوجد شيء خاطئ في ذلك ، في جميع الأمثلة التي سأشرحها سأستخدم ملفالمكتبة الموعودة IndexedDBبواسطة Jake Archibald ، وهي طبقة صغيرة أعلى واجهة برمجة تطبيقات IndexedDB لتسهيل استخدامها.
تُستخدم هذه المكتبة أيضًا في جميع الأمثلة الموجودة على موقع Google Developers فيما يتعلق بقاعدة البيانات المفهرسة
إنشاء قاعدة بيانات مفهرسة
إن أبسط طريقة هي الاستخدامunpkg، من خلال إضافة هذا إلى رأس الصفحة:
<script type="module">
import { openDB, deleteDB } from 'https://unpkg.com/idb?module'
</script>
قبل استخدام IndexedDB API ، تأكد دائمًا من التحقق من الدعم في المتصفح ، على الرغم من توفره على نطاق واسع ، فأنت لا تعرف أبدًا أي متصفح يستخدمه المستخدم:
(() => {
'use strict'
if (!(‘indexedDB’ in window)) {
console.warn(‘IndexedDB not supported’)
return
}
//…IndexedDB code
})()
كيفإنشاء قاعدة بيانات
استخدامopenDB()
:
(async () => {
//...
const dbName = 'mydbname'
const storeName = 'store1'
const version = 1 //versions start at 1
const db = await openDB(dbName, version, {
upgrade(db, oldVersion, newVersion, transaction) {
const store = db.createObjectStore(storeName)
}
})
})()
المعلمتان الأوليان هما اسم قاعدة البيانات والإصدار. المعلمة الثالثة ، وهي اختيارية ، هي كائن يحتوي على وظيفةيتم استدعاؤه فقط إذا كان رقم الإصدار أعلى من إصدار قاعدة البيانات المثبتة حاليًا. في جسم الوظيفة ، يمكنك ترقية البنية (المخازن والفهارس) لـ db.
إضافة البيانات إلى المتجر
إضافة البيانات عند إنشاء المتجر وتهيئته
أنت تستخدمput
طريقة تخزين الكائن ، لكننا نحتاج أولاً إلى مرجع لها ، والذي يمكننا الحصول عليه منdb.createObjectStore()
عندما نقوم بإنشائه.
عند استخدامput
، القيمة هي الوسيطة الأولى ، المفتاح هو الثاني. هذا لأنه إذا حددتkeyPath
عند إنشاء ملف تخزين العناصر ، لا تحتاج إلى إدخال اسم المفتاح في كل طلب put () ، يمكنك فقط كتابة القيمة.
هذا يسكنstore0
بمجرد إنشائه:
(async () => {
//...
const dbName = 'mydbname'
const storeName = 'store0'
const version = 1
const db = await openDB(dbName, version,{
upgrade(db, oldVersion, newVersion, transaction) {
const store = db.createObjectStore(storeName)
store.put(‘Hello world!’, ‘Hello’)
}
})
})()
إضافة البيانات عند إنشاء المتجر بالفعل باستخدام المعاملات
لإضافة عناصر في وقت لاحق على الطريق ، تحتاج إلى إنشاء قراءة / كتابةعملية تجارية، الذي يضمن تكامل قاعدة البيانات (إذا فشلت عملية ما ، يتم إرجاع جميع العمليات في المعاملة إلى الوراء وتعود الحالة إلى حالة معروفة).
لذلك ، استخدم إشارة إلىdbPromise
الشيء الذي حصلنا عليه عند الاتصالopenDB
، و اهرب:
(async () => {
//...
const dbName = 'mydbname'
const storeName = 'store0'
const version = 1
const db = await openDB(/* … */)
const tx = db.transaction(storeName, ‘readwrite’)
const store = await tx.objectStore(storeName)
const val = ‘hey!’
const key = ‘Hello again’
const value = await store.put(val, key)
await tx.done
})()
الحصول على البيانات من متجر
الحصول على عنصر واحد من متجر:get()
const key = 'Hello again'
const item = await db.transaction(storeName).objectStore(storeName).get(key)
الحصول على جميع العناصر من متجر:getAll()
احصل على جميع المفاتيح المخزنة
const items = await db.transaction(storeName).objectStore(storeName).getAllKeys()
احصل على جميع القيم المخزنة
const items = await db.transaction(storeName).objectStore(storeName).getAll()
حذف البيانات من قاعدة البيانات المفهرسة
حذف قاعدة البيانات ومخزن العناصر والبيانات
حذف قاعدة بيانات IndexedDB بأكملها
const dbName = 'mydbname'
await deleteDB(dbName)
لحذف البيانات في ملف تخزين العناصر
نحن نستخدم معاملة:
(async () => {
//...
const dbName = 'mydbname'
const storeName = 'store1'
const version = 1
const db = await openDB(dbName, version, {
upgrade(db, oldVersion, newVersion, transaction) {
const store = db.createObjectStore(storeName)
}
})
const tx = await db.transaction(storeName, ‘readwrite’)
const store = await tx.objectStore(storeName)
const key = ‘Hello again’
await store.delete(key)
await tx.done
})()
الترحيل من الإصدار السابق لقاعدة البيانات
المعلمة الثالثة (الاختيارية) لملفopenDB()
الوظيفة هي كائن يمكن أن يحتوي علىupgrade
وظيفةيتم استدعاؤه فقط إذا كان رقم الإصدار أعلى من إصدار قاعدة البيانات المثبتة حاليًا. في هيئة الوظيفة هذه ، يمكنك ترقية البنية (المخازن والفهارس) لـ db:
const name = 'mydbname'
const version = 1
openDB(name, version, {
upgrade(db, oldVersion, newVersion, transaction) {
console.log(oldVersion)
}
})
في رد الاتصال هذا ، يمكنك التحقق من الإصدار الذي يقوم المستخدم بتحديثه ، وتنفيذ بعض العمليات وفقًا لذلك.
يمكنك إجراء ترحيل من إصدار قاعدة بيانات سابق باستخدام بناء الجملة هذا
(async () => {
//...
const dbName = 'mydbname'
const storeName = 'store0'
const version = 1
const db = await openDB(dbName, version, {
upgrade(db, oldVersion, newVersion, transaction) {
switch (oldVersion) {
case 0: // no db created before
// a store introduced in version 1
db.createObjectStore(‘store1’)
case 1:
// a new store in version 2
db.createObjectStore(‘store2’, { keyPath: ‘name’ })
}
db.createObjectStore(storeName)
}
})
})()
مفاتيح فريدة
createObjectStore()
كما ترى فيcase 1
يقبل معلمة ثانية تشير إلى مفتاح الفهرس لقاعدة البيانات. هذا مفيد جدًا عند تخزين العناصر:put()
لا تحتاج المكالمات إلى معلمة ثانية ، ولكن يمكنها فقط أن تأخذ القيمة (كائن) وسيتم تعيين المفتاح إلى خاصية الكائن التي تحمل هذا الاسم.
يمنحك الفهرس طريقة لاسترداد قيمة لاحقًا بواسطة هذا المفتاح المحدد ، ويجب أن يكون فريدًا (يجب أن يكون لكل عنصر مفتاح مختلف)
يمكن تعيين مفتاح على زيادة تلقائية ، لذلك لا تحتاج إلى تتبعه على رمز العميل:
db.createObjectStore('notes', { autoIncrement: true })
استخدم الزيادة التلقائية إذا كانت قيمك لا تحتوي على مفتاح فريد بالفعل (على سبيل المثال ، إذا قمت بجمع عناوين البريد الإلكتروني بدون اسم مرتبط).
تحقق من وجود متجر
يمكنك التحقق مما إذا كان ملف تخزين العناصر موجودًا بالفعل عن طريق استدعاءobjectStoreNames()
طريقة:
const storeName = 'store1'
if (!db.objectStoreNames.contains(storeName)) {
db.createObjectStore(storeName)
}
الحذف من IndexedDB
حذف قاعدة البيانات ومخزن العناصر والبيانات
احذف قاعدة البيانات
await deleteDB('mydb')
حذف ملف تخزين العناصر
لا يمكن حذف ملف تخزين العناصر إلا في رد الاتصال عند فتح db ، ولا يتم استدعاء رد النداء هذا إلا إذا قمت بتحديد إصدار أعلى من الإصدار المثبت حاليًا:
const db = await openDB('dogsdb', 2, {
upgrade(db, oldVersion, newVersion, transaction) {
switch (oldVersion) {
case 0: // no db created before
// a store introduced in version 1
db.createObjectStore('store1')
case 1:
// delete the old store in version 2, create a new one
db.deleteObjectStore('store1')
db.createObjectStore('store2')
}
}
})
لحذف البيانات في ملف تخزين العناصر ، استخدم معاملة
const key = 232 //a random key
const db = await openDB(/*...*/)
const tx = await db.transaction('store', 'readwrite')
const store = await tx.objectStore('store')
await store.delete(key)
await tx.complete
هناك المزيد!
هذه هي الأساسيات فقط. لم أتحدث عن المؤشرات والأشياء الأكثر تقدمًا. هناك المزيد في IndexedDB ولكن آمل أن يمنحك هذا السبق.
تحميل مجانيدليل جافا سكريبت للمبتدئين
المزيد من دروس المتصفح:
- تتوفر بعض الحيل المفيدة في HTML5
- كيف أنشأت موقع ويب يستند إلى CMS يعمل دون اتصال بالإنترنت
- الدليل الكامل لتطبيقات الويب التقدمية
- واجهة برمجة تطبيقات الجلب
- دليل Push API
- واجهة برمجة تطبيقات Channel Messaging
- دروس عمال الخدمة
- دليل ذاكرة التخزين المؤقت API
- دليل API الإخطار
- الغوص في IndexedDB
- واجهة برمجة تطبيقات المحددات: querySelector و querySelectorAll
- تحميل JavaScript بكفاءة مع التأجيل وغير المتزامن
- نموذج كائن المستند (DOM)
- واجهة برمجة تطبيقات Web Storage: التخزين المحلي وتخزين الجلسة
- تعرف على كيفية عمل ملفات تعريف الارتباط HTTP
- واجهة برمجة تطبيقات التاريخ
- تنسيق صورة WebP
- طلب XMLHttpRequest (XHR)
- برنامج تعليمي متعمق SVG
- ما هي عناوين URL للبيانات
- خارطة الطريق لتعلم منصة الويب
- CORS ، تقاسم الموارد عبر الأصول
- عمال الويب
- دليل requestAnimationFrame ()
- ما هو النوع
- العمل مع DevTools Console وواجهة برمجة تطبيقات وحدة التحكم
- واجهة برمجة تطبيقات تركيب الكلام
- كيفية انتظار حدث جاهز لـ DOM في JavaScript عادي
- كيفية إضافة فئة إلى عنصر DOM
- كيفية تكرار عناصر DOM من querySelectorAll
- كيفية إزالة فئة من عنصر DOM
- كيفية التحقق من وجود فئة لعنصر DOM
- كيفية تغيير قيمة عقدة DOM
- كيفية إضافة حدث نقرة إلى قائمة عناصر DOM التي تم إرجاعها من querySelectorAll
- WebRTC ، واجهة برمجة تطبيقات الويب في الوقت الفعلي
- كيفية الحصول على موضع التمرير لعنصر في JavaScript
- كيفية استبدال عنصر DOM
- كيفية قبول الصور فقط في حقل ملف الإدخال
- لماذا تستخدم نسخة معاينة من المتصفح؟
- كائن النقطة
- كائن الملف
- كائن FileReader
- كائن FileList
- ArrayBuffer
- ArrayBufferView
- كائن URL
- صفائف من النوع
- كائن DataView
- واجهة برمجة تطبيقات BroadcastChannel
- واجهة برمجة تطبيقات Streams
- كائن FormData
- كائن المستكشف
- كيفية استخدام واجهة برمجة تطبيقات تحديد الموقع الجغرافي
- كيفية استخدام getUserMedia ()
- كيفية استخدام Drag and Drop API
- كيفية العمل مع التمرير على صفحات الويب
- التعامل مع النماذج في JavaScript
- أحداث لوحة المفاتيح
- أحداث الماوس
- أحداث اللمس
- كيفية إزالة جميع العناصر الأبناء من عنصر DOM
- كيفية إنشاء سمة HTML باستخدام Vanilla Javascript
- كيف تتحقق مما إذا كان مربع الاختيار محددًا باستخدام JavaScript؟
- كيفية النسخ إلى الحافظة باستخدام JavaScript
- كيفية تعطيل زر باستخدام JavaScript
- كيفية جعل صفحة قابلة للتحرير في المتصفح
- كيفية الحصول على قيم سلسلة الاستعلام في JavaScript باستخدام URLSearchParams
- كيفية إزالة جميع CSS من صفحة مرة واحدة
- كيفية استخدام insertAdjacentHTML
- سفاري ، حذر قبل الإقلاع عن التدخين
- كيفية إضافة صورة إلى DOM باستخدام JavaScript
- كيفية إعادة تعيين نموذج
- كيفية استخدام خطوط جوجل