Сохраните их как строку ASCII и сделайте поле индексом.
EDIT
Egads, я случайно делать некоторые тыкать о, и наткнулся на это. Какой позорный ответ. В тот день, должно быть, у меня было настроение. Если бы я мог, я бы просто удалил его и продолжил. Тем не менее, это невозможно, поэтому я расскажу об обновлении.
Во-первых, единственный способ узнать, что является «эффективным», - это измерить, учитывая время и пространство программы, а также сложность исходного кода и усилия программиста.
К счастью, этот довольно прост.
Я написал очень простое приложение OSX. Модель состоит из одного атрибута: identifier
.
Ничего из этого не имеет значения, если вы не отмечаете свой атрибут как индекс. При создании магазина потребуется гораздо больше времени, но он будет делать запросы намного быстрее.
Кроме того, обратите внимание, что при создании предиката для бинарного атрибута является точно такой же, как создание одного для строки:
fetchRequest.predicate =
[NSPredicate predicateWithFormat:@"identifier == %@", identifier];
Приложение очень просто. Во-первых, он создает N объектов и присваивает UUID атрибуту идентификатора. Он сохраняет MOC каждые 500 объектов. Затем мы сохраняем все идентификаторы в массив и произвольно перетасовываем их. Затем весь CD-стоп полностью разорван, чтобы удалить все из памяти.
Затем мы снова создаем стек, а затем перебираем идентификаторы и делаем простую выборку. Объект fetch построен с простым предикатом для извлечения этого одного объекта. Все это делается внутри autoreleasepool, чтобы каждый выбор был как можно более чистым (я признаю, что будет некоторое взаимодействие с кэшами CD). Это не так важно, поскольку мы просто сравниваем разные методы.
Двоичный идентификатор - это 16-байты для UUID.
UUID String - это 36-байтовая строка, результат вызова [uuid UUIDString], и это выглядит так (B85E91F3-4A0A-4ABB-A049-83B2A8E6085E).
Base64 String - это 24-байтовая строка, в результате которой базовый 64 кодирует 16-байтовые двоичные данные UUID, и он выглядит так (uF6R80oKSrugSYOyqOYIXg ==) для того же UUID.
Count - количество объектов для этого запуска.
Размер SQLite - это размер фактического файла sqlite.
WAL размер как большой получает файл WAL (с упреждением каротаж) - просто FYI ...
Создать это количество секунд, чтобы создать базу данных, в том числе экономии.
Запрос - это количество секунд для запроса каждого объекта.
Data Type | Count (N) | SQLite Size | WAL Size | Create | Query
--------------+-----------+-------------+-----------+---------+---------
Binary | 100,000 | 5,758,976 | 5,055,272 | 2.6013 | 9.2669
Binary | 1,000,000 | 58,003,456 | 4,783,352 | 59.0179 | 96.1862
UUID String | 100,000 | 10,481,664 | 4,148,872 | 3.6233 | 9.9160
UUID String | 1,000,000 | 104,947,712 | 5,792,752 | 68.5746 | 93.7264
Base64 String | 100,000 | 7,741,440 | 5,603,232 | 3.0207 | 9.2446
Base64 String | 1,000,000 | 77,848,576 | 4,931,672 | 63.4510 | 94.5147
Первое, что нужно отметить, что фактический размер базы данных намного больше, чем байт сохраняемое (1600000 и 16000000) - что можно ожидать для базы данных. Объем дополнительного хранилища будет несколько относительно размера ваших реальных объектов ... этот хранит только идентификатор, поэтому процент накладных расходов будет выше).
Во-вторых, по вопросам скорости, для справки, выполнение одного и того же 1,000 000 объектного запроса, но с использованием идентификатора объекта в выборке потребовалось около 82 секунд (обратите внимание на резкую разницу между этим и вызовом existingObjectWithID:error:
, который занял колоссальные 0,3065 секунды).
Вы должны создать собственную базу данных, в том числе разумное использование инструментов в текущем коде. Я предполагаю, что цифры будут несколько отличаться, если я сделал несколько прогонов, но они настолько близки, что это необязательно для этого анализа.
Однако, исходя из этих чисел, давайте посмотрим на измерения эффективности для выполнения кода.
- Как и ожидалось, сохранение исходных двоичных данных UUID более эффективно с точки зрения пространства.
- Время создания довольно близко (различие, по-видимому, зависит от времени создания строк и дополнительного пространства для хранения).
- Времена запроса кажутся почти идентичными, при этом двоичная строка выглядит немного медленнее. Я думаю, что это была первоначальная проблема - выполнение запроса по двоичному атрибуту.
Двоичный выигрывает пространство по большому счету, и его можно считать близким тиражом как по времени создания, так и по времени запроса. Если мы просто рассмотрим их, то сохранение двоичных данных станет явным победителем.
Как насчет сложности исходного кода и времени программиста?
Хорошо, если вы используете современную версию iOS и OSX, практически нет разницы, особенно с простой категорией на NSUUID.
Однако для вас есть одно соображение, и это простота использования данных в базе данных. Когда вы храните двоичные данные, трудно получить хороший визуал данных.
Итак, если по какой-то причине вы хотите, чтобы данные в базе данных были сохранены более эффективным образом для людей, то сохранение его в виде строки является лучшим выбором. Таким образом, вы можете рассмотреть кодировку base64 (или некоторую другую кодировку, хотя помните, что она уже находится в кодировке base-256).
FWIW, вот пример категории, чтобы обеспечить легкий доступ к UUID как оба NSData и base64 строки:
- (NSData*)data
{
uuid_t rawuuid;
[self getUUIDBytes:rawuuid];
return [NSData dataWithBytes:rawuuid length:sizeof(rawuuid)];
}
- (NSString*)base64String
{
uuid_t rawuuid;
[self getUUIDBytes:rawuuid];
NSData *data = [NSData dataWithBytesNoCopy:rawuuid length:sizeof(rawuuid) freeWhenDone:NO];
return [data base64EncodedStringWithOptions:0];
}
- (instancetype)initWithBase64String:(NSString*)string
{
NSData *data = [[NSData alloc] initWithBase64EncodedString:string options:0];
if (data.length == sizeof(uuid_t)) {
return [self initWithUUIDBytes:data.bytes];
}
return self = nil;
}
- (instancetype)initWithString:(NSString *)string
{
if ((self = [self initWithUUIDString:string]) == nil) {
self = [self initWithBase64String:string];
}
return self;
}
вы знаете, что доступ к UDID были устаревшим прошивкой 5, да? –
OP говорит о UUID, которые отличаются от UDID. –
@JodyHagins, вы правы. UUID, о котором я упоминал, является универсальным уникальным идентификатором для ManagedObjects, созданным моим приложением. –