在iOS上创建键值存储数据库的一个示例是YapDatabase。
但是,我没有使用它的经验,并且想了解使用它是否值得,而不是像Core Data或FMDB那样。
我遇到的一个关键问题是:如何管理与此数据库的对象关系?
如果我可以避免对象关系,我正在寻找关于如何解决与另一个对象具有多对多关系的对象问题的建议或数据库设计技巧。
让我们考虑一个用例(这只是一个例子,以帮助解决这个问题):
sender <<->> message <<->> recipient
sender has a:
photo_data,
name,
gender,
age,
email,
username,
twitter_id,
facebook_id,
sender_id
recipient has a:
photo_data,
name,
gender,
age,
email,
username,
twitter_id,
facebook_id,
recipient_id
message has a:
text,
rich_text,
picture_data,
voice_data,
shared_url,
message_id
我考虑过使用message_id,sender_id和recipient_id来关联每个模型,但是有更好的方法吗?
答案 0 :(得分:5)
我做过类似的事情,这可能不太合适,但可能有所帮助。
我有一个类似的聊天应用程序设置。每封邮件都有发件人和收件人,但显然当前用户是其中之一。所以我将所有消息存储在他们自己的集合中,其中集合的名称是非当前用户的id。
如果使用YapDatabase,则使用YapCollectionsDatabase类。
==编辑==
你首先要发表你的信息&amp;用户类:
@interface Message : NSObject <NSCoding> ...
@property (...) NSString *sender_id;
@property (...) NSString *recipient_id;
@property (...) NSString *user_id; // sender_id || recipient_id (non-current-user)
@property (...) NSDate *timestamp;
...
@end
@interface User : NSObject <NSCoding>
@property (...) NSString *user_id;
...
@end
现在将这些对象存储在数据库中。
我们从YapCollectionsDatabase开始。这是一个集合/键/值存储。因此,当新消息到达时,我们只将其存储在适当的集合中
[dbConnection readWriteWithBlock:^(YapCollectionsDatabaseReadWriteTransaction *transaction){
[transaction setObject:messsage
forKey:uuid
inCollection:message.user_id
withMetadata:message.timestamp];
}];
因此每条消息都是单独存储的。但它被放置在一个集合中,其中包含对话中的所有其他消息。此外,添加新消息很快,因为您只是将一行添加到数据库中。
在sqlite数据库内部看起来像这样: |收集|键|对象|元数据|
要查找会话数,或获取会话的userIds:
[dbConnection readWithBlock:^(YapCollectionsDatabaseReadTransaction *transaction){
conversationCount = [transaction numberOfCollections];
conversationUserIds = [transaction allCollections];
}];
获取对话中的消息数或消息的ID:
[dbConnection readWithBlock:^(YapCollectionsDatabaseReadTransaction *transaction){
messageCount = [transaction numberOfKeysInCollection:user_id];
messageIdsSorted = [transaction allKeysOrdered:NSOrderedAscending
inCollection:user_id];
}];
要从数据库中删除旧邮件:
[dbConnection readWriteWithBlock:^(YapCollectionsDatabaseReadWriteTransaction *transaction){
[transaction removeObjectsEarlierThan:twoWeeksAgo inCollection:user_id];
}];
希望这有帮助。