تخزين البيانات المتطابقة بكفاءة في نموذج بيانات البيانات الأساسية
-
05-07-2019 - |
سؤال
لدي نموذج بيانات يحتوي على عدة كيانات، لكل منها عدة سمات مختلفة تقوم بتخزين بيانات الصورة.ستكون هذه جميعها صورًا صغيرة وأحتاج إلى تخزينها في المتجر الدائم وليس كملفات خارجية.
بينما يمكنني فقط تخزين بيانات الصورة في سمة ثنائية أو قابلة للتحويل، فمن المحتمل جدًا أن يحدد المستخدم صورًا متطابقة لاثنين أو أكثر من هذه السمات، لذلك أفضل تخزين نسخة واحدة من كل صورة فريدة بدلاً من تكرار الصورة بيانات.
لقد أخطأت في إنشاء كيان "ImageBlob" لتخزين بيانات الصورة واستخدام العلاقات للقيام بذلك ولكني مبتدئ في استخدام البيانات الأساسية وليس من الواضح لي على الفور ما إذا كانت هذه هي الطريقة الصحيحة للذهاب.وعلى وجه الخصوص، كيف أتعامل مع المواقف التالية؟
- أريد أن تستخدم جميع سمات الصور الخاصة بي في كيانات متعددة نفس "مخزن بيانات الصورة" بحيث يتم تخزين مثيل واحد فقط لكل صورة ثنائية كبيرة الحجم
- أحتاج إلى التأكد من أنه في حالة عدم وجود كائنات تستخدم صورة في مخزن البيانات، فسيتم إزالتها
ما هي أفضل طريقة للتعامل مع هذا؟
المحلول
سؤالي الأول هو كيف تخطط لتحديد متى يستخدم كائنان نفس الصورة؟هل هناك خاصية في الصورة يمكنك تخزينها والاستعلام عنها لتحديد ما إذا كانت الصورة التي تقوم بإعدادها موجودة بالفعل؟وما مدى تكلفة ذلك من الناحية الحسابية؟إذا استغرق الأمر الكثير من الوقت، فقد ينتهي بك الأمر إلى تحسين مساحة التخزين والتأثير على الأداء.
ومع ذلك، إذا كان لديك طريقة للقيام بذلك بكفاءة، فيمكنك إنشاء ملف ImageBlob
كيان للقيام بما تصفه.الجهة التي تستخدم ImageBlob
يجب أن يكون لديك imageBlob
أو imageBlobs
علاقة مع ImageBlob
. ImageBlob
يجب أن تكون لها علاقة عكسية مع اسم مثل، على سبيل المثال، users
.
في التعليمات البرمجية الخاصة بك، عندما تريد إعادة استخدام ImageBlob
, ، الأمر بسيط مثل القيام بشيء مثل هذا:
NSManagedObject *blob = // get the image blob
NSManagedObject *user = // get the user
[user setValue:blob forKey:@"imageBlob"]; // do this if it uses a single image
[[user mutableSetValueForKey:@"imageBlobs"] addObject:blob]; // do this if it uses multiple images
هناك اعتبار آخر تريد التفكير فيه وهو ما يجب فعله بالنقط التي لم تعد هناك حاجة إليها.من المفترض أنك تريد إسقاط أي صور غير مستخدمة.للقيام بذلك، يمكنك تسجيل مندوب التطبيق الخاص بك أو NSPersistentDocument
فئة فرعية (اعتمادًا على ما إذا كان تطبيقك يعتمد على المستند أم لا) لـ NSManagedObjectContextObjectsDidChangeNotification
إشعار.عندما يتغير سياق الكائن المُدار، يمكنك حذف أي صور غير ضرورية مثل هذا:
- (void)managedObjectContextObjectsDidSave:(NSNotification *)notification {
NSManagedObjectContext *managedObjectContext = [notification object];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntity entityWithName:@"ImageBlob" inManagedObjectContext:managedObjectContext]];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"users.@count == 0"];
NSArray *unusedBlobs = [managedObjectContext executeFetchRequest:fetchRequest error:nil]; // Don't be stupid like me; catch and handle the error
[fetchRequest release];
for (NSManagedObject *blob in unusedBlobs) {
[managedObjectContext deleteObject:blob];
}
}
نصائح أخرى
يمكنك إضافة خاصية فريدة تسمى md5 إلى ملف Image
الكيان للتأكد من أنك تقوم بتخزين نفس الصور مرة واحدة فقط.
أما بالنسبة لأشياء البيانات الأساسية، أعتقد أن شيئًا كهذا قد ينجح:ثم قم بإنشاء كيان أصل مجرد (Parent
).إضافة علاقة من Parent
ل Image
مُسَمًّى image
, ، وقم بتعيين "Cascade" لطريقة الحذف بحيث يتم ذلك عند الحذف Parent
, Image
تم حذفه أيضًا.إضافة علاقة من Image
ل Parent
مُسَمًّى parent
, ، أو أيًا كان، وقم بتعيين "Nullify" لطريقة الحذف بحيث يتم حذفها عند حذفها Image
, الصورة ل Parent
تم ضبطه على nil
.ثم قم بإضافة الكيانات الأخرى الخاصة بك وقم بتعيين الكيانات الرئيسية الخاصة بها Parent
.