SlideShare a Scribd company logo
YapDatabase
Головко Михаил
YapDatabase
Problem?
Рамблер Гороскопы
YapDatabase
План
• Реляционные и нереляционные БД
• Хранение и работа с данными в YapDatabase
• Расширения YapDatabase
• YapDatabase + VIPER
YapDatabase
Реляционная БД
Реляционная база данных — это совокупность
взаимосвязанных таблиц, каждая из которых
содержит информацию об объектах определенного
типа.
Таблицы реляционной БД должны отвечать
требованиям нормализации отношений.
YapDatabase
Реляционная БД
Плюсы
• Нет дублирования информации
• Над таблицами можно производить различные
операции
• Данные в таблице имеют чётко определённую
структуру
• Целостность данных гарантируется БД
YapDatabase
Реляционная БД
Минусы
• Для получения объекта со всеми связями нужно
делать сложные запросы
• Нужно поддерживать базу в нормализованном
виде
YapDatabase
Реляционная БД
YapDatabase
Нереляционная БД
Хранилище типа ключ-значение.
Это совокупность доменов (коллекций), каждый из
которых содержит объект любого типа.
YapDatabase
Нереляционная БД
Плюсы
• Динамическая модель данных, которая заранее
может быть не определена
• В рамках одного домена (коллекции) данные
могут иметь различную структуру
• Несвязанность данных
YapDatabase
Нереляционная БД
Минусы
• Контроль целостности данных лежит на
приложении
• Избыточность данных
YapDatabase
Нереляционная БД
YapDatabase
YapDatabase
• Нереляционная база данных (key/value)
• Открытый исходный код
• мм
• Контрибъютит Google
YapDatabase
Организация данных
collection key object metadata
sound 34 blob blob
album elvis blob blob
album ac/dc blob blob
sound 15 blob blob
sound 16 blob blob
YapDatabase
Коллекции
Sound
Album
Artist
YapDatabase
Коллекции
Elvis AC/DC
YapDatabase
Коллекции
Список Опубликованный Черновой
YapDatabase
Object
• Любой объект
• Для сохранения объекта используется NSCoding
• Можно описать свои Serializer/Deserializer
YapDatabase
Metadata
• Сохранение любой информацию
• json из которого был получен объект
• timestamp создания
• Опциональное поле
YapDatabase
Connection
• Подключение к базе, через которое можно
работать с данными
• Аналог NSManagedObjectContext
• Одно соединение на запись
• Несколько на чтение для ui
YapDatabase
Connection
YapDatabase *database = [[YapDatabase alloc] initWithPath:path];
YapDatabaseConnection *connection = [database newConnection];
YapDatabase
Transaction
• Обеспечивают доступ к данным базы
• Чтения и Записи
• Синхронные и асинхронные
YapDatabase
Connection
read
Transaction
Connection Connection
read
read
read
read
read
read
read
read
t
i
m
e
YapDatabase
Connection
write 1
Transaction
Connection Connection
read
read
read
read
write 2
read
write 3
read
Write Queue
t
i
m
e
YapDatabase
write 1
Connection
write 1
Transaction
Connection Connection
read
read
read
read
write 2
read
write 3
read
Write Queue
t
i
m
e
YapDatabase
Connection
write 1
Transaction
Connection Connection
read
read
read
read
write 2
read
write 3
read
Write Queue
write 1
write 2
t
i
m
e
YapDatabase
Connection
write
Transaction
Connection Connection
read
read
read
read
write 2
read
write 3
read
Write Queue
write 1 write 1
write 2
t
i
m
e
write 3
YapDatabase
Connection
write
Transaction
Connection Connection
read
read
read
read
write 2
read
write 3
read
Write Queue
write 1 write 1
write 2
write 3
t
i
m
e
YapDatabase
Transaction
• Транзакции в соединении выполняются
последовательно
• Все транзакции записи синхронизируются одной
глобальной очередью
YapDatabase
Transaction
// Write
[connection readWriteWithBlock:
^(YapDatabaseReadWriteTransaction *transaction) {
[transaction setObject:@"Hello"
forKey:@“World"
inCollection:@"example1"];
}];
// Read
[connection readWithBlock:
^(YapDatabaseReadTransaction *transaction) {
NSLog(@"%@ World", [transaction objectForKey:@“World"
inCollection:@"example1"]);
}];
YapDatabase
Кэширование
• Используется соединениями
• В зависимости от политики, различный подход к
работе с объектами
• Можно изменять размер и сбрасывать во время
выполнения
YapDatabase
Политики кэширования
• YapDatabasePolicyContainment - объекты
всегда достаются из базы
• YapDatabasePolicyShare - между всеми
соединениями шарятся одни экземпляры
объектов
• YapDatabasePolicyCopy - между соединениями
объекты копируются
YapDatabase
YapDatabaseTransaction
YapDatabaseConnection
Cache
TransactionQueue
Структура
YapDatabase
Serializer/Deserializer
Extensions
WriteQueue
SQLite
Расширения
YapDatabase
View
• Похоже на NSFetchedResultsController
• Вычисляется на этапе записи в БД
• Данные группированы по коллекциям
• Данные отсортированы
• Данные отфильтрованы
• Может содержать различные объекты
• Ручное обновление данных немного сложнее, чем
NSFetchedResultsController
YapDatabase
View
@{
@"books" : @[
@{@"fiction",@"key24"},
@{@"fantasy",@"key7"},
@{@"mystery",@"key11"}
],
@"magazines" : @[
@{@"gossip",@"key60"},
@{@"science",@"key49"},
@{@"travel",@"key82"}
]
};
YapDatabase
View
YapDatabaseViewGrouping *grouping = [YapDatabaseViewGrouping withRowBlock:
^NSString *(YapDatabaseReadTransaction *transaction,
NSString *collection, NSString *key, id object, id metadata) {
if ([object isKindOfClass:[BNBook class]])
return @"books";
return nil;
};
YapDatabaseViewSorting *sorting = [YapDatabaseViewSorting withObjectBlock:
^(YapDatabaseReadTransaction *transaction, NSString *group,
NSString *collection1, NSString *key1, id obj1
NSString *collection2, NSString *key2, id obj2) {
return [obj1 compareBookByTitleThenAuthor:obj2];
};
YapDatabaseView *databaseView =
[[YapDatabaseView alloc] initWithGrouping:grouping
sorting:sorting];
YapDatabase
Mapping (View)
NSIndexPath
UITableView YapDatabaseView
section
row
group
index
YapDatabase
Mapping (View)
• Настраивать список групп, их порядок
• Можно реверсировать данные
• Динамические и статические секции
• Динамически и статически диапазон
• Зависимость ячеек от другой
YapDatabase
Mapping (View)
YapDatabaseViewMappings *mappings = [YapDatabaseViewMappings
mappingsWithGroups:@[@"bond movies", @"bond actors" ]
view:@“myView"];
[mappings setIsDynamicSection:YES forGroup:@"bond movies”];
[mappings setIsReversed:YES forGroup:@"bond actors"];
YapDatabase
Mapping (View)
- (NSInteger)numberOfSectionsInTableView:(UITableView *)sender {
return [mappings numberOfSections];
}
- (NSInteger)tableView:(UITableView *)sender numberOfRowsInSection
(NSInteger)section {
return [mappings numberOfItemsInSection:section];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
__block id object = nil;
[databaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction){
object = [[transaction ext:@"myView"] objectAtIndexPath:indexPath
withMappings:mappings];
}];
// configure and return cell...
}
YapDatabase
YapDatabaseTransaction
YapDatabaseConnection
Cache
TransactionQueue
Структура
YapDatabase
Serializer/Deserializer
Extensions
WriteQueue
SQLite
YapDatabase
YapDatabaseViewMappingsYapDatabaseTransactionYapDatabaseViewTransaction
YapDatabaseConnection
Cache
TransactionQueue
Структура
YapDatabase
Serializer/Deserializer
Extensions
WriteQueue
SQLite
YapDatabaseExtension
YapDatabaseViewConnection
YapDatabase
FilteredViews
• Позволяет фильтровать View
• Поддерживает все возможности View
• Динамическое изменение фильтра
• Иерархия FilteredView!!!
YapDatabase
FilteredViews
YapDatabaseViewFiltering *filtering =
[YapDatabaseViewFiltering withObjectBlock:
^BOOL (YapDatabaseReadTransaction *transaction,
NSString *group, NSString *collection,
NSString *key, id object) {
return [(PhoneCall *)object isMissed];
}];
YapDatabaseFilteredView *filteredView =
[[YapDatabaseFilteredView alloc] initWithParentViewName:@"view-object"
filtering:filtering
versionTag:@"0"];
YapDatabase
Relationships
Правила one-to-one
• DeleteSourceIfDestinationDeleted
• DeleteDestinationIfSourceDeleted
Правила one-to-many
• DeleteSourceIfAllDestinationsDeleted
• DeleteDestinationIfAllSourcesDeleted
YapDatabase
Relationships
Правила уведомлений
• NotifyIfSourceDeleted
• NotifyIfDestinationDeleted
YapDatabase
Relationships
@implementation Player
- (nullable NSArray<YapDatabaseRelationshipEdge *> *)yapDatabaseRelationshipEdges {
if (avatarID == nil) return nil;
YapDatabaseRelationshipEdge *edge = // (player) --> (avatar)
[YapDatabaseRelationshipEdge edgeWithName:@"avatar"
destinationKey:avatarID
collection:@"avatars"
nodeDeleteRules:YDB_DeleteDestinationIfSourceDeleted |
YDB_NotifyIfDestinationDeleted];
return @[ edge ];
}
- (nullable id)yapDatabaseRelationshipEdgeDeleted:(YapDatabaseRelationshipEdge *)edge
withReason:(YDB_NotifyReason)reason {
if ([edge.name isEqualToString:@“avatar"]) {
id copy = [self copy];
copy.avatarID = nil;
return copy;
}
return nil;
}
YapDatabase
CoreData + VIPER
Interactor Service
NSManagedObject
Context
Presenter
PONSO mapping
YapDatabase
CoreData + VIPER
Interactor Service
NSManagedObject
Context
Presenter
PONSO mapping
NSManagedObject
YapDatabase
CoreData + VIPER
Interactor Service
NSManagedObject
Context
Presenter
PONSO mapping
NSManagedObject
YapDatabase
CoreData + VIPER
Interactor Service
NSManagedObject
Context
Presenter
PONSO mapping
NSManagedObject
YapDatabase
CoreData + VIPER
Interactor Service
NSManagedObject
Context
Presenter
PONSO mapping
NSManagedObject
YapDatabase
CoreData + VIPER
Interactor Service
NSManagedObject
Context
Presenter
PONSO mapping
PONSO
YapDatabase
CoreData + VIPER
Interactor Service
NSManagedObject
Context
Presenter
PONSO mapping
PONSO
YapDatabase
CoreData + VIPER
Interactor Service
NSManagedObject
Context
Presenter
PONSO mapping
PONSO
YapDatabase
YapDatabase + VIPER
Interactor Service
YapDatabase
Connection
Presenter
YapDatabase
YapDatabase + VIPER
Interactor Service
YapDatabase
Connection
Presenter
PONSO
YapDatabase
YapDatabase + VIPER
Interactor Service
YapDatabase
Connection
Presenter
PONSO
YapDatabase
YapDatabase + VIPER
Interactor Service
YapDatabase
Connection
Presenter
PONSO
YapDatabase
YapDatabase + VIPER
Interactor Service
YapDatabase
Connection
Presenter
PONSO
YapDatabase
Итог
Плюсы
• Нет NSManagedObject
• Если мы запросили данные - они точно будут
• Можно оптимизировать работу с данными при
помощи кэширования
• Не нужна перегонка объектов из
NSManagedObject в PONSO
YapDatabase
Итог
Плюсы
• Объекты можно использовать в разных потоках
• View с разнотипными объектами
• Можно писать свои расширения !
YapDatabase
Итог
Минусы
• Ручная миграция
• Нет понимания работы с коллекциями
• Сложная работа с relation
• Все данные объекта выгружаются в памяти
• Если нужны связи из других коллекций, их нужно
доставать отдельно
Стоит попробовать в наших
проектах?
Да
Конец

More Related Content

PDF
Hadoop -> Cascading -> Cascalog
PDF
Active Record for CoreData
PPT
базы данных в Delphi
PDF
лек13 5
PDF
Rambler.iOS #5: Подмодули в VIPER
PDF
Влад Ковташ — Yap Database
PDF
Rambler.iOS #5: VIPER a la Rambler
PDF
Rambler.iOS #5: Переходы и передача данных между VIPER модулями
Hadoop -> Cascading -> Cascalog
Active Record for CoreData
базы данных в Delphi
лек13 5
Rambler.iOS #5: Подмодули в VIPER
Влад Ковташ — Yap Database
Rambler.iOS #5: VIPER a la Rambler
Rambler.iOS #5: Переходы и передача данных между VIPER модулями

Viewers also liked (15)

PDF
Rambler.iOS #7: Прием платежей по банковским картам в iOS приложении
PDF
RDSDataSource: Мастер-класс по Dip
PDF
Rambler.iOS #7: Интернет-эквайринг 101
PDF
Rambler.iOS #8: Как не стать жертвой бэкендеров
PDF
RDSDataSource: OCLint
PDF
RDSDataSource: Promises
PDF
RDSDataSource: Автогенерация документации для SDK
PDF
Rambler.iOS #5: Разбираем Massive View Controller
PDF
Rambler.iOS #6: Не рычите на pbxproj
PDF
RDSDataSource: App Thinning
PDF
Rambler.iOS #7: Построение сложного табличного интерфейса
PDF
Rambler.iOS #4: Создание модульных приложений на примере Рамблер.Кассы
PDF
RDSDataSource: Чистые тесты на Swift
PDF
RDSDataSource: iOS Reverse Engineering for inexperienced
PDF
Rambler.iOS #5: VIPER и Swift
Rambler.iOS #7: Прием платежей по банковским картам в iOS приложении
RDSDataSource: Мастер-класс по Dip
Rambler.iOS #7: Интернет-эквайринг 101
Rambler.iOS #8: Как не стать жертвой бэкендеров
RDSDataSource: OCLint
RDSDataSource: Promises
RDSDataSource: Автогенерация документации для SDK
Rambler.iOS #5: Разбираем Massive View Controller
Rambler.iOS #6: Не рычите на pbxproj
RDSDataSource: App Thinning
Rambler.iOS #7: Построение сложного табличного интерфейса
Rambler.iOS #4: Создание модульных приложений на примере Рамблер.Кассы
RDSDataSource: Чистые тесты на Swift
RDSDataSource: iOS Reverse Engineering for inexperienced
Rambler.iOS #5: VIPER и Swift
Ad

More from RAMBLER&Co (13)

PDF
RDSDataSource: Основы LLVM
PDF
Rambler.iOS #9: Анализируй это!
PDF
Rambler.iOS #9: Нужны ли бэкенд-разработчики, когда есть Swift?
PDF
Rambler.iOS #9: Life with out of memory
PDF
RDSDataSource: Построение UML диаграмм
PDF
Rambler.iOS #8: Чистые unit-тесты
PDF
Rambler.iOS #8: Сервис-ориентированная архитектура
PDF
Rambler.iOS #8: Make your app extensible with JavaScriptCore
PDF
RDSDataSource: Плюрализация в iOS
PDF
RDSDataSource: Flux, Redux, ReSwift
PDF
Rambler.iOS #6: App delegate - разделяй и властвуй
PDF
Rambler.iOS #6: Pagination Demystified
PDF
Rambler.iOS #5: TDD и VIPER
RDSDataSource: Основы LLVM
Rambler.iOS #9: Анализируй это!
Rambler.iOS #9: Нужны ли бэкенд-разработчики, когда есть Swift?
Rambler.iOS #9: Life with out of memory
RDSDataSource: Построение UML диаграмм
Rambler.iOS #8: Чистые unit-тесты
Rambler.iOS #8: Сервис-ориентированная архитектура
Rambler.iOS #8: Make your app extensible with JavaScriptCore
RDSDataSource: Плюрализация в iOS
RDSDataSource: Flux, Redux, ReSwift
Rambler.iOS #6: App delegate - разделяй и властвуй
Rambler.iOS #6: Pagination Demystified
Rambler.iOS #5: TDD и VIPER
Ad

RDSDataSource: YapDatabase