Realmdagi kaskadli o'chirish uzoq vaqt davomida qanday g'alaba qozonishi haqidagi ertak

Barcha foydalanuvchilar mobil ilovalarda tezkor ishga tushirish va sezgir UI ni qabul qilishadi. Agar ilovani ishga tushirish uchun uzoq vaqt kerak bo'lsa, foydalanuvchi g'amgin va g'azablana boshlaydi. Siz mijozning tajribasini osongina buzishingiz yoki foydalanuvchi dasturdan foydalanishni boshlashdan oldin uni butunlay yo'qotishingiz mumkin.

Bir paytlar Dodo Pizza ilovasini ishga tushirish uchun o‘rtacha 3 soniya, ba’zi “baxtlilar” uchun esa 15-20 soniya vaqt ketishini aniqladik.

Kesim ostida baxtli yakun bilan hikoya: Realm ma'lumotlar bazasining o'sishi, xotiraning oqishi, biz qanday qilib o'rnatilgan ob'ektlarni to'plaganimiz va keyin o'zimizni birlashtirganimiz va hamma narsani tuzatganimiz haqida.

Realmdagi kaskadli o'chirish uzoq vaqt davomida qanday g'alaba qozonishi haqidagi ertak

Realmdagi kaskadli o'chirish uzoq vaqt davomida qanday g'alaba qozonishi haqidagi ertak
Maqola muallifi: Maksim Kachinkin — Dodo Pizza kompaniyasida Android dasturchisi.

Ilova belgisini bosgandan so'ng birinchi faoliyatning onResume() ga qadar uch soniya davom etadi. Va ba'zi foydalanuvchilar uchun ishga tushirish vaqti 15-20 soniyaga etdi. Qanday qilib bu mumkin?

O'qishga vaqti bo'lmaganlar uchun juda qisqa xulosa
Bizning Realm ma'lumotlar bazasi cheksiz o'sib bordi. Ba'zi ichki o'rnatilgan ob'ektlar o'chirilmadi, lekin doimiy ravishda to'planib turardi. Ilovani ishga tushirish vaqti asta-sekin oshdi. Keyin biz uni tuzatdik va ishga tushirish vaqti maqsadga yetdi - u 1 soniyadan kamroq vaqtni oldi va endi oshmadi. Maqolada vaziyat tahlili va ikkita yechim mavjud - tezkor va oddiy.

Muammoni izlash va tahlil qilish

Bugungi kunda har qanday mobil ilova tez ishga tushishi va sezgir bo'lishi kerak. Lekin bu faqat mobil ilova haqida emas. Xizmat va kompaniya bilan o'zaro aloqada foydalanuvchi tajribasi murakkab narsadir. Misol uchun, bizning holatlarimizda etkazib berish tezligi pizza xizmatining asosiy ko'rsatkichlaridan biridir. Yetkazib berish tez bo'lsa, pitsa issiq bo'ladi va hozir ovqatlanmoqchi bo'lgan mijoz uzoq kutmaydi. Ilova uchun, o'z navbatida, tezkor xizmat ko'rsatish tuyg'usini yaratish muhim, chunki agar ilova ishga tushishiga atigi 20 soniya kerak bo'lsa, unda pitsani qancha kutish kerak bo'ladi?

Avvaliga biz o'zimiz ham ba'zida dasturni ishga tushirish uchun bir necha soniya vaqt ketishiga duch keldik, keyin esa boshqa hamkasblarimizdan qancha vaqt ketgani haqida shikoyatlarni eshita boshladik. Ammo biz bu holatni doimiy ravishda takrorlay olmadik.

Qancha vaqt? Ga binoan Google hujjatlari, agar dasturning sovuq boshlanishi 5 soniyadan kamroq vaqtni talab qilsa, bu "odatdagidek" hisoblanadi. Dodo Pizza Android ilovasi ishga tushirildi (Firebase ko'rsatkichlariga ko'ra _ilova_start) da sovuq boshlanish o'rtacha 3 soniyada - ular aytganidek, "Ajoyib emas, dahshatli emas".

Ammo keyin arizani ishga tushirish juda, juda va juda uzoq vaqt talab qilgani haqida shikoyatlar paydo bo'la boshladi! Boshlash uchun biz "juda, juda, juda uzoq" nima ekanligini o'lchashga qaror qildik. Buning uchun biz Firebase izidan foydalandik Ilovaning boshlanishi izi.

Realmdagi kaskadli o'chirish uzoq vaqt davomida qanday g'alaba qozonishi haqidagi ertak

Ushbu standart kuzatuv foydalanuvchi dasturni ochgan vaqt va birinchi faoliyatning onResume() bajarilgan vaqti o'rtasidagi vaqtni o'lchaydi. Firebase konsolida bu ko'rsatkich _app_start deb ataladi. Ma'lum bo'ldiki:

  • O'rtacha sovuq ishga tushirish vaqti 95 soniyadan kam bo'lishiga qaramay, 20 foizdan yuqori bo'lgan foydalanuvchilar uchun ishga tushirish vaqtlari deyarli 5 soniyani tashkil qiladi (ba'zilari undan ham uzoqroq).
  • Ishga tushirish vaqti doimiy qiymat emas, balki vaqt o'tishi bilan o'sib boradi. Ammo ba'zida tomchilar bor. Biz tahlil ko'lamini 90 kunga oshirganimizda ushbu naqshni topdik.

Realmdagi kaskadli o'chirish uzoq vaqt davomida qanday g'alaba qozonishi haqidagi ertak

Miyaga ikkita fikr keldi:

  1. Nimadir oqmoqda.
  2. Ushbu "narsa" chiqarilgandan keyin qayta tiklanadi va keyin yana oqadi.

"Ehtimol, ma'lumotlar bazasi bilan bir narsa", deb o'yladik va biz haq edik. Birinchidan, biz ma'lumotlar bazasidan kesh sifatida foydalanamiz, migratsiya paytida biz uni tozalaymiz. Ikkinchidan, dastur ishga tushganda ma'lumotlar bazasi yuklanadi. Hammasi bir-biriga mos keladi.

Realm ma'lumotlar bazasida nima noto'g'ri

Ilovaning ishlash muddati davomida, birinchi o'rnatishdan boshlab va faol foydalanish paytida ma'lumotlar bazasi tarkibi qanday o'zgarishini tekshirishni boshladik. Siz Realm ma'lumotlar bazasi tarkibini orqali ko'rishingiz mumkin steto yoki orqali faylni ochish orqali batafsil va aniq Realm Studio. Ma'lumotlar bazasi tarkibini ADB orqali ko'rish uchun Realm ma'lumotlar bazasi faylidan nusxa oling:

adb exec-out run-as ${PACKAGE_NAME} cat files/${DB_NAME}

Turli vaqtlarda ma'lumotlar bazasi tarkibini ko'rib chiqib, biz ma'lum turdagi ob'ektlar soni doimiy ravishda ko'payib borayotganini aniqladik.

Realmdagi kaskadli o'chirish uzoq vaqt davomida qanday g'alaba qozonishi haqidagi ertak
Rasmda Realm Studio-ning ikkita fayl uchun fragmenti ko'rsatilgan: chapda - o'rnatishdan biroz vaqt o'tgach dastur bazasi, o'ngda - faol foydalanishdan keyin. Ko'rinib turibdiki, ob'ektlar soni ImageEntity и MoneyType sezilarli darajada o'sdi (skrinshotda har bir turdagi ob'ektlar soni ko'rsatilgan).

Ma'lumotlar bazasi o'sishi va ishga tushirish vaqti o'rtasidagi bog'liqlik

Ma'lumotlar bazasining nazoratsiz o'sishi juda yomon. Ammo bu dasturni ishga tushirish vaqtiga qanday ta'sir qiladi? Buni ActivityManager orqali o'lchash juda oson. Android 4.4 dan boshlab logcat jurnalni ko'rsatilgan qator va vaqt bilan ko'rsatadi. Bu vaqt dastur ishga tushirilgan paytdan boshlab faoliyatni ko'rsatishning oxirigacha bo'lgan vaqt oralig'iga teng. Bu vaqt ichida quyidagi hodisalar ro'y beradi:

  • Jarayonni boshlang.
  • Ob'ektlarni ishga tushirish.
  • Faoliyatlarni yaratish va ishga tushirish.
  • Tartib yaratish.
  • Ilovani ko'rsatish.

Bizga yarashadi. Agar siz ADB-ni -S va -W bayroqlari bilan ishga tushirsangiz, ishga tushirish vaqti bilan kengaytirilgan natijalarni olishingiz mumkin:

adb shell am start -S -W ru.dodopizza.app/.MainActivity -c android.intent.category.LAUNCHER -a android.intent.action.MAIN

Agar siz uni o'sha erdan tutsangiz grep -i WaitTime Vaqt o'tishi bilan siz ushbu ko'rsatkichni yig'ishni avtomatlashtirishingiz va natijalarni vizual tarzda ko'rishingiz mumkin. Quyidagi grafik dasturni ishga tushirish vaqtining dasturni sovuq ishga tushirish soniga bog'liqligini ko'rsatadi.

Realmdagi kaskadli o'chirish uzoq vaqt davomida qanday g'alaba qozonishi haqidagi ertak

Shu bilan birga, ma'lumotlar bazasi hajmi va o'sishi o'rtasidagi bog'liqlikning bir xil xususiyati mavjud bo'lib, u 4 MB dan 15 MB gacha o'sdi. Umuman olganda, vaqt o'tishi bilan (sovuq boshlanishining o'sishi bilan) dasturni ishga tushirish vaqti ham, ma'lumotlar bazasi hajmi ham oshdi. Bizning qo'limizda gipoteza bor. Endi faqat qaramlikni tasdiqlash qoldi. Shuning uchun, biz "oqishlarni" olib tashlashga qaror qildik va bu ishga tushirishni tezlashtiradimi yoki yo'qligini bilib oldik.

Ma'lumotlar bazasining cheksiz o'sishining sabablari

"Oqish" ni olib tashlashdan oldin, nima uchun ular birinchi navbatda paydo bo'lganligini tushunish kerak. Buning uchun keling, Realm nima ekanligini eslaylik.

Realm - bu aloqador bo'lmagan ma'lumotlar bazasi. Bu sizga Android-da qancha ORM relyatsion ma'lumotlar bazasi tasvirlanganiga o'xshash tarzda ob'ektlar orasidagi munosabatlarni tasvirlash imkonini beradi. Shu bilan birga, Realm ob'ektlarni to'g'ridan-to'g'ri xotirada eng kam miqdordagi transformatsiyalar va xaritalar bilan saqlaydi. Bu sizga diskdan ma'lumotlarni juda tez o'qish imkonini beradi, bu Realmning kuchi va nima uchun uni sevadi.

(Ushbu maqolaning maqsadlari uchun ushbu tavsif biz uchun etarli bo'ladi. Siz Realm haqida ko'proq ma'lumot olishingiz mumkin hujjatlar yoki ularning ichida akademiyasi).

Ko'pgina ishlab chiquvchilar relyatsion ma'lumotlar bazalari bilan ko'proq ishlashga odatlangan (masalan, SQL ostidagi ORM ma'lumotlar bazalari). Va kaskadli ma'lumotlarni o'chirish kabi narsalar ko'pincha berilgan kabi ko'rinadi. Ammo Realmda emas.

Aytgancha, kaskadni o'chirish xususiyati uzoq vaqtdan beri so'ralgan. Bu qayta ko'rib chiqish и boshqa, u bilan bog'liq, faol muhokama qilindi. Tez orada amalga oshadi degan tuyg'u bor edi. Ammo keyin hamma narsa kuchli va zaif havolalarning kiritilishiga aylandi, bu ham bu muammoni avtomatik ravishda hal qiladi. Bu vazifada ancha jonli va faol edi tortish so'rovi, ichki qiyinchiliklar tufayli hozircha to'xtatilgan.

Kaskadli o'chirishsiz ma'lumotlarning oqishi

Mavjud bo'lmagan kaskadli o'chirishga tayansangiz, ma'lumotlar qanday qilib oqadi? Agar sizda Realm ob'ektlari o'rnatilgan bo'lsa, ular o'chirilishi kerak.
Keling, (deyarli) haqiqiy misolni ko'rib chiqaylik. Bizda ob'ekt bor CartItemEntity:

@RealmClass
class CartItemEntity(
 @PrimaryKey
 override var id: String? = null,
 ...
 var name: String = "",
 var description: String = "",
 var image: ImageEntity? = null,
 var category: String = MENU_CATEGORY_UNKNOWN_ID,
 var customizationEntity: CustomizationEntity? = null,
 var cartComboProducts: RealmList<CartProductEntity> = RealmList(),
 ...
) : RealmObject()

Savatdagi mahsulot turli maydonlarga, jumladan, rasmga ega ImageEntity, moslashtirilgan ingredientlar CustomizationEntity. Bundan tashqari, aravadagi mahsulot o'ziga xos mahsulotlar to'plamiga ega kombinatsiya bo'lishi mumkin RealmList (CartProductEntity). Roʻyxatdagi barcha maydonlar Realm obyektlaridir. Agar biz bir xil identifikatorga ega bo'lgan yangi ob'ektni (copyToRealm() / copyToRealmOrUpdate()) qo'shsak, bu ob'ekt butunlay qayta yoziladi. Ammo barcha ichki ob'ektlar (tasvir, customizationEntity va cartComboProducts) ota-ona bilan aloqani yo'qotadi va ma'lumotlar bazasida qoladi.

Ular bilan aloqa uzilganligi sababli, biz endi ularni o'qimaymiz yoki o'chirmaymiz (agar biz ularga aniq kirishmasak yoki butun "jadval"ni tozalamasak). Biz buni "xotira qochqinlari" deb nomladik.

Realm bilan ishlaganimizda, biz barcha elementlarni aniq ko'rib chiqishimiz va bunday operatsiyalardan oldin hamma narsani aniq o'chirishimiz kerak. Buni, masalan, shunday qilish mumkin:

val entity = realm.where(CartItemEntity::class.java).equalTo("id", id).findFirst()
if (first != null) {
 deleteFromRealm(first.image)
 deleteFromRealm(first.customizationEntity)
 for(cartProductEntity in first.cartComboProducts) {
   deleteFromRealm(cartProductEntity)
 }
 first.deleteFromRealm()
}
// и потом уже сохраняем

Agar buni qilsangiz, hamma narsa kerakli tarzda ishlaydi. Ushbu misolda biz image, customizationEntity va cartComboProducts ichida boshqa ichki o'rnatilgan Realm ob'ektlari yo'q deb taxmin qilamiz, shuning uchun boshqa ichki o'rnatilgan tsikllar va o'chirishlar yo'q.

"Tezkor" yechim

Biz qilishga qaror qilgan birinchi narsa, eng tez o'sadigan ob'ektlarni tozalash va bu bizning asl muammomizni hal qiladimi yoki yo'qligini bilish uchun natijalarni tekshirish edi. Birinchidan, eng oddiy va intuitiv yechim amalga oshirildi, ya'ni: har bir ob'ekt o'z farzandlarini olib tashlash uchun javobgar bo'lishi kerak. Buning uchun biz o'zining ichki o'rnatilgan Realm ob'ektlari ro'yxatini qaytaradigan interfeysni taqdim etdik:

interface NestedEntityAware {
 fun getNestedEntities(): Collection<RealmObject?>
}

Va biz uni Realm ob'ektlarimizda amalga oshirdik:

@RealmClass
class DataPizzeriaEntity(
 @PrimaryKey
 var id: String? = null,
 var name: String? = null,
 var coordinates: CoordinatesEntity? = null,
 var deliverySchedule: ScheduleEntity? = null,
 var restaurantSchedule: ScheduleEntity? = null,
 ...
) : RealmObject(), NestedEntityAware {

 override fun getNestedEntities(): Collection<RealmObject?> {
   return listOf(
       coordinates,
       deliverySchedule,
       restaurantSchedule
   )
 }
}

В getNestedEntities biz barcha bolalarni tekis ro'yxat sifatida qaytaramiz. Va har bir kichik ob'ekt NestedEntityAware interfeysini ham amalga oshirishi mumkin, bu uning o'chirish uchun ichki Realm ob'ektlari mavjudligini ko'rsatadi, masalan ScheduleEntity:

@RealmClass
class ScheduleEntity(
 var monday: DayOfWeekEntity? = null,
 var tuesday: DayOfWeekEntity? = null,
 var wednesday: DayOfWeekEntity? = null,
 var thursday: DayOfWeekEntity? = null,
 var friday: DayOfWeekEntity? = null,
 var saturday: DayOfWeekEntity? = null,
 var sunday: DayOfWeekEntity? = null
) : RealmObject(), NestedEntityAware {

 override fun getNestedEntities(): Collection<RealmObject?> {
   return listOf(
       monday, tuesday, wednesday, thursday, friday, saturday, sunday
   )
 }
}

Va hokazo, ob'ektlarning uyasi takrorlanishi mumkin.

Keyin biz barcha ichki o'rnatilgan ob'ektlarni rekursiv ravishda yo'q qiladigan usulni yozamiz. Usul (kengaytma sifatida yaratilgan) deleteAllNestedEntities barcha yuqori darajadagi ob'ektlar va usullarni oladi deleteNestedRecursively NestedEntityAware interfeysi yordamida barcha ichki o'rnatilgan ob'ektlarni rekursiv ravishda olib tashlaydi:

fun <T> Realm.deleteAllNestedEntities(entities: Collection<T>,
 entityClass: Class<out RealmObject>,
 idMapper: (T) -> String,
 idFieldName : String = "id"
 ) {

 val existedObjects = where(entityClass)
     .`in`(idFieldName, entities.map(idMapper).toTypedArray())
     .findAll()

 deleteNestedRecursively(existedObjects)
}

private fun Realm.deleteNestedRecursively(entities: Collection<RealmObject?>) {
 for(entity in entities) {
   entity?.let { realmObject ->
     if (realmObject is NestedEntityAware) {
       deleteNestedRecursively((realmObject as NestedEntityAware).getNestedEntities())
     }
     realmObject.deleteFromRealm()
   }
 }
}

Biz buni eng tez o'sadigan ob'ektlar bilan qildik va nima bo'lganini tekshirdik.

Realmdagi kaskadli o'chirish uzoq vaqt davomida qanday g'alaba qozonishi haqidagi ertak

Natijada, biz ushbu yechim bilan qoplagan ob'ektlar o'sishni to'xtatdi. Va bazaning umumiy o'sishi sekinlashdi, lekin to'xtamadi.

"Oddiy" yechim

Baza sekinroq o'sishni boshlagan bo'lsa-da, u hali ham o'sdi. Shunday qilib, biz ko'proq izlay boshladik. Bizning loyihamiz Realm-da ma'lumotlarni keshlashdan juda faol foydalanadi. Shuning uchun, har bir ob'ekt uchun barcha ichki o'rnatilgan ob'ektlarni yozish ko'p mehnat talab qiladi, bundan tashqari, xatolar xavfi ortadi, chunki kodni o'zgartirganda ob'ektlarni belgilashni unutishingiz mumkin.

Men interfeyslardan foydalanmasligimga ishonch hosil qilmoqchi edim, lekin hamma narsa o'z-o'zidan ishlagan.

Agar biror narsa o'z-o'zidan ishlashini xohlasak, biz aks ettirishdan foydalanishimiz kerak. Buni amalga oshirish uchun biz har bir sinf maydonini ko'rib chiqishimiz va uning Realm ob'ekti yoki ob'ektlar ro'yxati ekanligini tekshirishimiz mumkin:

RealmModel::class.java.isAssignableFrom(field.type)

RealmList::class.java.isAssignableFrom(field.type)

Agar maydon RealmModel yoki RealmList bo'lsa, ushbu maydon ob'ektini ichki o'rnatilgan ob'ektlar ro'yxatiga qo'shing. Hammasi yuqorida qilganimizdek bir xil, faqat bu erda u o'z-o'zidan amalga oshiriladi. Kaskadni o'chirish usulining o'zi juda oddiy va quyidagicha ko'rinadi:

fun <T : Any> Realm.cascadeDelete(entities: Collection<T?>) {
 if(entities.isEmpty()) {
   return
 }

 entities.filterNotNull().let { notNullEntities ->
   notNullEntities
       .filterRealmObject()
       .flatMap { realmObject -> getNestedRealmObjects(realmObject) }
       .also { realmObjects -> cascadeDelete(realmObjects) }

   notNullEntities
       .forEach { entity ->
         if((entity is RealmObject) && entity.isValid) {
           entity.deleteFromRealm()
         }
       }
 }
}

Kengaytma filterRealmObject faqat Realm obyektlarini filtrlaydi va uzatadi. Usul getNestedRealmObjects aks ettirish orqali u barcha ichki o'rnatilgan Realm obyektlarini topadi va ularni chiziqli ro'yxatga kiritadi. Keyin biz xuddi shu narsani rekursiv ravishda qilamiz. O'chirishda siz ob'ektning haqiqiyligini tekshirishingiz kerak isValid, chunki turli ota-onalar bir xil ob'ektlarga ega bo'lishi mumkin. Buning oldini olish va yangi ob'ektlarni yaratishda identifikatorni avtomatik yaratishdan foydalanish yaxshiroqdir.

Realmdagi kaskadli o'chirish uzoq vaqt davomida qanday g'alaba qozonishi haqidagi ertak

getNestedRealmObjects usulini to'liq amalga oshirish

private fun getNestedRealmObjects(realmObject: RealmObject) : List<RealmObject> {
 val nestedObjects = mutableListOf<RealmObject>()
 val fields = realmObject.javaClass.superclass.declaredFields

// Проверяем каждое поле, не является ли оно RealmModel или списком RealmList
 fields.forEach { field ->
   when {
     RealmModel::class.java.isAssignableFrom(field.type) -> {
       try {
         val child = getChildObjectByField(realmObject, field)
         child?.let {
           if (isInstanceOfRealmObject(it)) {
             nestedObjects.add(child as RealmObject)
           }
         }
       } catch (e: Exception) { ... }
     }

     RealmList::class.java.isAssignableFrom(field.type) -> {
       try {
         val childList = getChildObjectByField(realmObject, field)
         childList?.let { list ->
           (list as RealmList<*>).forEach {
             if (isInstanceOfRealmObject(it)) {
               nestedObjects.add(it as RealmObject)
             }
           }
         }
       } catch (e: Exception) { ... }
     }
   }
 }

 return nestedObjects
}

private fun getChildObjectByField(realmObject: RealmObject, field: Field): Any? {
 val methodName = "get${field.name.capitalize()}"
 val method = realmObject.javaClass.getMethod(methodName)
 return method.invoke(realmObject)
}

Natijada, mijoz kodimizda biz har bir ma'lumotlarni o'zgartirish operatsiyasi uchun "kaskadli o'chirish" dan foydalanamiz. Misol uchun, kiritish operatsiyasi uchun u quyidagicha ko'rinadi:

override fun <T : Entity> insert(
 entityInformation: EntityInformation,
 entities: Collection<T>): Collection<T> = entities.apply {
 realmInstance.cascadeDelete(getManagedEntities(entityInformation, this))
 realmInstance.copyFromRealm(
     realmInstance
         .copyToRealmOrUpdate(this.map { entity -> entity as RealmModel }
 ))
}

Birinchi usul getManagedEntities barcha qo'shilgan ob'ektlarni, keyin esa usulni oladi cascadeDelete Yangilarini yozishdan oldin barcha to'plangan ob'ektlarni rekursiv ravishda o'chiradi. Biz dastur davomida ushbu yondashuvdan foydalanamiz. Realm-da xotiraning oqishi butunlay yo'qoldi. Ilovani ishga tushirish vaqtining sovuq ishga tushirish soniga bog'liqligini bir xil o'lchashni amalga oshirib, biz natijani ko'ramiz.

Realmdagi kaskadli o'chirish uzoq vaqt davomida qanday g'alaba qozonishi haqidagi ertak

Yashil chiziq dasturni ishga tushirish vaqtining ichki o'rnatilgan ob'ektlarni avtomatik kaskad o'chirish paytida sovuq ishga tushirish soniga bog'liqligini ko'rsatadi.

Natijalar va xulosalar

Doim o'sib borayotgan Realm ma'lumotlar bazasi dasturning juda sekin ishga tushishiga sabab bo'ldi. Biz o'rnatilgan ob'ektlarni "kaskadli o'chirish" bilan yangilanishni chiqardik. Endi biz qarorimiz ilovani ishga tushirish vaqtiga qanday ta'sir qilganini _app_start ko'rsatkichi orqali kuzatib boramiz va baholaymiz.

Realmdagi kaskadli o'chirish uzoq vaqt davomida qanday g'alaba qozonishi haqidagi ertak

Tahlil qilish uchun biz 90 kunlik vaqtni olamiz va ko'ramiz: dasturni ishga tushirish vaqti, ham o'rtacha, ham foydalanuvchilarning 95 foizli qismiga to'g'ri keladigan vaqt pasayishni boshladi va endi ko'tarilmaydi.

Realmdagi kaskadli o'chirish uzoq vaqt davomida qanday g'alaba qozonishi haqidagi ertak

Agar yetti kunlik jadvalga qarasangiz, _app_start koʻrsatkichi toʻliq mos va 1 soniyadan kamroq vaqtni tashkil qiladi.

Shuni ham ta'kidlash kerakki, agar _app_start o'rtacha qiymati 5 soniyadan oshsa, Firebase sukut bo'yicha bildirishnomalarni yuboradi. Biroq, biz ko'rib turganimizdek, siz bunga tayanmasligingiz kerak, aksincha, kirib, uni aniq tekshirib ko'ring.

Realm ma'lumotlar bazasining o'ziga xos tomoni shundaki, u aloqador bo'lmagan ma'lumotlar bazasi. Foydalanish qulayligi, ORM yechimlariga o'xshashligi va ob'ektlarni bog'lashiga qaramay, u kaskadli o'chirishga ega emas.

Agar bu e'tiborga olinmasa, u holda o'rnatilgan ob'ektlar to'planib, "oqib ketadi". Ma'lumotlar bazasi doimiy ravishda o'sib boradi, bu esa o'z navbatida dasturning sekinlashishiga yoki ishga tushishiga ta'sir qiladi.

Men Realmdagi ob'ektlarni kaskadli o'chirishni qanday tezda amalga oshirish bo'yicha tajribamiz bilan o'rtoqlashdim, bu hali qutidan chiqmagan, lekin uzoq vaqtdan beri muhokama qilinmoqda. ular aytadilar и ular aytadilar. Bizning holatda, bu dasturni ishga tushirish vaqtini sezilarli darajada tezlashtirdi.

Ushbu xususiyatning yaqinda paydo bo'lishi haqidagi munozaralarga qaramay, Realm-da kaskad o'chirishning yo'qligi dizayn tomonidan amalga oshiriladi. Agar siz yangi dastur yaratmoqchi bo'lsangiz, buni hisobga oling. Va agar siz allaqachon Realm dan foydalanayotgan bo'lsangiz, bunday muammolaringiz borligini tekshiring.

Manba: www.habr.com

a Izoh qo'shish