36
YapDatabase Key-Value store and Much More Built atop SQLite for iOS & Mac

Влад Ковташ — Yap Database

Embed Size (px)

Citation preview

Page 1: Влад Ковташ — Yap Database

YapDatabaseKey-Value store and Much More

Built atop SQLite for iOS & Mac

Page 2: Влад Ковташ — Yap Database

СвойстваТранзакционность

Потокобезопасность

Параллелизм

Высокая производительность

Низкое потребление памяти

Расширяемость

Современный API, построенный на блоках

Page 3: Влад Ковташ — Yap Database

ВозможностиViews - Доступ к базе в стиле UITableViewDatasource ианимация изменений

Secondary Indexes - Поиск объектов в стиле SQL

Full Text Search - Полнотекстовый поиск на базе FTS модуляSQLite

Relationships - Механизм, похожий на deletion rules в CoreData

CloudKit - Интеграция с CloudKit (beta)

Whole Database Encryption - Обеспечивается SQLCipher

Page 4: Влад Ковташ — Yap Database

Структура доклада

Архитектура YapDatabase

Расширения, которые делают жизнь приятной

Page 5: Влад Ковташ — Yap Database

Архитектура YapDatabase

Page 6: Влад Ковташ — Yap Database

collection key data metadata

movies movie_56757 BLOB BLOB

actors actor_546 BLOB BLOB

genres genre_13 BLOB BLOB

movies movie_95456 BLOB BLOB

Схема данных хранилища

Составной primary key - collection, key

Page 7: Влад Ковташ — Yap Database

@{ @"collection_1": @{ @"key1": @[object, metadata], @"key2": @[object, metadata], //... }, @"collection_2": @{ @"key1": @[object, metadata], @"key2": @[object, metadata], //... } //...};

Структура хранилища в виде NSDictionary

Page 8: Влад Ковташ — Yap Database

Основные понятия

База данных - YapDatabase

Подключение - YapDatabaseConnection

Транзакция - YapDatabaseTransaction

Page 9: Влад Ковташ — Yap Database

YapDatabase *database = [[YapDatabase alloc] initWithPath:@"yap_db.sqlite"];

База данных (YapDatabase)Только один экземпляр YapDatabase может иметь доступ к файлу базы.

Page 10: Влад Ковташ — Yap Database

YapDatabaseConnection *connection = [database newConnection];

Подключение (YapDatabaseConnection)У одной базы данных может быть несколько подключений.

Page 11: Влад Ковташ — Yap Database

Транзакции

Два основных типа транзакций: YapDatabaseReadTransaction иYapDatabaseReadWriteTransaction

SQLite транзакции + механизм snaphot & changeset

Полностью соотвествуют ACID

Page 12: Влад Ковташ — Yap Database

Snapshot & Changeset

Snapshot - 64-битное число, которое инкрементируется послезавершения каждой транзакции записи

Changeset - Структура даных, описывающая изменения,произошедшие в транзакции

Page 13: Влад Ковташ — Yap Database

Потокобезопасность ипараллелизм

Доступ к подключениям может осуществляться из любогопотока. Потокопезопасность возвращаемых объектов необеспечивается базой данных.

Каждое подключение имеет свою последовательную очередь

База данных имеет глобальную последовательную очередьдля синхронизации записи

Транзакции чтения могут выполнятся параллельно

Транзакции записи выполняются последовательно иблокируют транзакции чтения

Page 14: Влад Ковташ — Yap Database

//YapDatabaseReadTransaction - могут быть использованы только для чтения[connection readWithBlock:^(YapDatabaseReadTransaction *transaction){

object1 = [transaction objectForKey:object1Key

inCollection:collection];

object2 = [transaction objectForKey:object2Key

inCollection:collection];

}];

//YapDatabaseReadWriteTransaction - могут быть использованы для чтения и записи[connection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction){

object = [transaction objectForKey:objectKey

inCollection:collection];

[transaction setObject:newObject

forKey:newObjectKey inCollection:collection];

[transaction replaceObject:updatedObject

forKey:updatedObjectKey inCollection:collection];

[transaction removeObjectForKey:removedObjectKey inCollection:collection];

}];

CRUD

Page 15: Влад Ковташ — Yap Database

Хранение объектов

По умолчанию используется NSCoding

Сериализация настраивается с помощью блоков

Page 16: Влад Ковташ — Yap Database

typedef NSData* (^YapDatabaseSerializer)(NSString *collection, NSString *key, id object);

typedef id (^YapDatabaseDeserializer)(NSString *collection, NSString *key, NSData *data);

- (instancetype)initWithPath:(NSString *)path serializer:(YapDatabaseSerializer)serializer deserializer:(YapDatabaseDeserializer)deserializer;

- (instancetype)initWithPath:(NSString *)path objectSerializer:(YapDatabaseSerializer)objectSerializer objectDeserializer:(YapDatabaseDeserializer)objectDeserializer metadataSerializer:(YapDatabaseSerializer)metadataSerializer metadataDeserializer:(YapDatabaseDeserializer)metadataDeserializer;

Настройка сериализации

Page 17: Влад Ковташ — Yap Database

Возможности сериализации

Хранение сущностей сетевой модели данных

Большой выбор сериализаторов - Mantle, JSONModel,

Protobuf, Thrift, Fastcoding, etc

Сжатие - lz4, Snappy

Выборочное шифрование записей

Page 18: Влад Ковташ — Yap Database

Кэширование

Каждое подключение имеет отдельные LRU кэши объектов иметаданных

Размеры кэшей могут быть настроены в процессе выполнения

Несколько политик кэширования

Page 19: Влад Ковташ — Yap Database

Политики кэширования

YapDatabasePolicyContainment - политика по умолчанию

YapDatabasePolicyCopy - требует от объектов поддержкиNSCopying

YapDatabasePolicyShare

Политики настраиваются раздельно для объектов и метаданных

Page 20: Влад Ковташ — Yap Database

РасширенияExtensions

Page 21: Влад Ковташ — Yap Database

Views

Page 22: Влад Ковташ — Yap Database

@{ @"books": @[ @[@"fiction", @"key24"], @[@"fantasy", @"key7"], @[@"mystery", @"key11"] ],

@"magazines": @[ @[@"gossip", @"key60"], @[@"science", @"key49"], @[@"travel", @"key82"] ]};

//В виде SQL-запроса//WHERE ... (filter)//GROUP BY ... (group)//ORDER BY ... (sort)

Структура в виде NSDictionaryСписок упорядоченных массивов пар Collection, Key

Page 23: Влад Ковташ — Yap Database

Свойства View

Персистентность (опционально)

Автоматическое обновление

Могут быть зарегистрированы и разрегистрированы в любоевремя

Транзакционность

Page 24: Влад Ковташ — Yap Database

YapDatabaseViewGrouping *grouping = nil;YapDatabaseViewSorting *sotring = nil;

grouping = [YapDatabaseViewGrouping withRowBlock:groupingBlock];sotring = [YapDatabaseViewSorting withRowBlock:sortingBlock];

YapDatabaseView *myView = [[YapDatabaseView alloc] initWithGrouping:grouping sorting:sotring];

Создание и регистрацияКаждое View содержит блок фильтрации/группировки и блок

сортировки.

Page 25: Влад Ковташ — Yap Database

groupingBlock = ^NSString *(NSString *collection, NSString *key,

id object, id metadata){

if ([object isKindOfClass:[Book class]])

return @"books";

if ([object isKindOfClass:[Magazine class]])

return @"magazines";

return nil; // exclude from view

};

sortingBlock = ^NSComparisonResult (NSString *group,

NSString *collection1, NSString *key1,

id obj1, id meta1,

NSString *collection2, NSString *key2,

id obj2, id meta2){

if ([group isEqualToString:@"books"])

return [obj1 compareBookByTitleThenAuthor:obj2];

else

return [obj1 compareMagazineByMonthThenTitle:obj2];

};

Пример блоков группировки и сортировкиСуществует несколько типов блоков. Отличаются они только набором

параметров, передающихся внутрь блока.

Page 26: Влад Ковташ — Yap Database

__block id objectForRow = nil;

[connection readWithBlock:^(YapDatabaseReadTransaction *transaction){

objectForRow = [[transaction ext:@"myViewName"] objectAtIndex:indexPath.row

inGroup:@"books"];

}];

//Некоторые другие методы View

(NSUInteger)numberOfGroups;

(NSArray *)allGroups;

(NSUInteger)numberOfItemsInGroup:(NSString *)group;

(NSUInteger)numberOfItemsInAllGroups;

(id)objectAtIndex:(NSUInteger)keyIndex inGroup:(NSString *)group;

Пример использования View

Page 27: Влад Ковташ — Yap Database

Анимация изменений View

YapDatabaseModifiedNotification

Long-Lived Read Transactions

Mappings

Page 28: Влад Ковташ — Yap Database

- (void)viewDidLoad

{

// ...

[connection beginLongLivedReadTransaction];

[[NSNotificationCenter defaultCenter] addObserver:self

selector:@selector(yapDatabaseModified:)

name:YapDatabaseModifiedNotification

object:connection.database];

// ...

}

- (void)yapDatabaseModified:(NSNotification *)notification

{

YapDatabaseConnection *connection = nil;

NSArray *notifications = [connection beginLongLivedReadTransaction];

}

YapDatabaseModifiedNotification иLong-Lived Read Transactions

Page 29: Влад Ковташ — Yap Database

//View@{ @"bond movies": @[ @[@"movies", @"abc123"], @[@"movies", @"xyz123"] ],

@"star wars": @[ @[@"movies", @"def456"] ],

@"batman movies": @[ @[@"movies", @"zxc567"], @[@"movies", @"asd567"] ] };

//Mapping

//Section 0@[ @[ @[@"movies", @"def456"] ], //Section 1 @[ @[@"movies", @"zxc567"], @[@"movies", @"asd567"] ], //Section 2 @[ @[@"movies", @"abc123"], @[@"movies", @"xyz123"] ] ];

Mappings (YapDatabaseViewMappings)Помогает перейти от понятия group-in-a-view к section-in-a-table

Page 30: Влад Ковташ — Yap Database

- (NSUInteger)numberOfSections;

- (NSUInteger)numberOfItemsInSection:(NSUInteger)section;

- (NSString *)groupForSection:(NSUInteger)section

//Методы транзакции- (id)objectAtIndexPath:(NSIndexPath *)indexPath

withMappings:(YapDatabaseViewMappings *)mappings;

- (id)objectAtRow:(NSUInteger)row

inSection:(NSUInteger)section

withMappings:(YapDatabaseViewMappings *)mappings;

Некоторые методыYapDatabaseViewMappings

Page 31: Влад Ковташ — Yap Database

- (void)yapDatabaseModified:(NSNotification *)notification{ NSArray *notifications = [connection beginLongLivedReadTransaction]; NSArray *sectionChanges = nil, *rowChanges = nil;

[[connection ext:@"movies"] getSectionChanges:&sectionChanges rowChanges:&rowChanges forNotifications:notifications withMappings:mappings];

if ([sectionChanges count] == 0 & [rowChanges count] == 0){ // Nothing has changed that affects our tableView return; } // Animate tableView updates ...}

Как YapDatabaseViewMappings помогаютанимировать таблицы?

Результатом будет массив изменений секций и ячеек, которые относятсяк указанному View c применением указанного mapping-a. На их основе

уже можно легко анимировать таблицы и коллекции.

Page 32: Влад Ковташ — Yap Database

Типы Mapping-ов

Статические - набор отображаемых групп и их порядокопределяется в момент создания

Динамические - при создании указываются блоки,определяющие видимость групп и способ их сортировки

Page 33: Влад Ковташ — Yap Database

//Статический мапингstaticMappings = [YapDatabaseViewMappings mappingsWithGroups:@[ @"bond movies", @"batman movies" ] view:@"movies"];//Можно инвертировать порядок сортировки элементов в группе[staticMappings setIsReversed:YES forGroup:@"bond movies"];

//Динамический мапингYapDatabaseViewMappingGroupFilter filterBlock = nil;YapDatabaseViewMappingGroupSort sortBlock = nil;

filterBlock = ^(NSString *group, YapDatabaseReadTransaction *transaction){ return YES; // include all movies groups};

sortBlock = ^(NSString *group1, NSString *group2, YapDatabaseReadTransaction *transaction){ return [group1 compare:group2]; // sorted by movie group name};

dynamicMappings = [[YapDatabaseViewMappings alloc] initWithGroupFilterBlock:filterBlock sortBlock:sortBlock view:@"movies"];

Создание Mapping-ов

Page 34: Влад Ковташ — Yap Database

Дополнительные возможности

Динамические секции - если в секции нет записей, она не

отображается

Статические диапазоны - аналог LIMIT & OFFSET в SQLite

Динамические диапазоны

Зависимость ячеек - для соседних ячеек могут быть

автоматически сгенерированы события, даже если связанный

с ячейкой объект не изменился

Page 35: Влад Ковташ — Yap Database

YapDatabase и CoreData

Page 36: Влад Ковташ — Yap Database

Спасибо за внимание

Влад Ковташ[email protected]

@VladKovtash