问题
One example of an effort to create a key value store database on the iOS is YapDatabase.
However, I have no experience with it, and would like to understand whether it's worth it to use this, instead of something like Core Data or FMDB.
One critical question I have is: How do I manage object relationships with this database?
If I can avoid object relationships, I'm looking for suggestion or database design tips on how to solve the problem of an object that has many-to-many relationship to another object.
Let's consider one use case (this is just an example, to help solving this problem):
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
I have thought about using the message_id, sender_id, and recipient_id to relate each model, but is there a better way?
回答1:
I've done something like this, which may not be an exact fit, but may help.
I had a similar setup for a chat application. Every message had a sender and recipient, but obviously the current user was one of the two. So I stored all the messages in their own collection, where the name of the collection was the id of the non-current-user.
If using YapDatabase, you'd use the YapCollectionsDatabase class.
== Edit ==
You'd start by making your message & user class:
@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
Now to store these objects in the database.
We start with YapCollectionsDatabase. This is a collection/key/value store. So when a new message arrives, we just store it in the proper collection
[dbConnection readWriteWithBlock:^(YapCollectionsDatabaseReadWriteTransaction *transaction){
[transaction setObject:messsage
forKey:uuid
inCollection:message.user_id
withMetadata:message.timestamp];
}];
So each message is stored separately. But it is placed in a collection with all other messages in the conversation. Further, adding a new message is fast because you're just adding a single row to the database.
Internally the sqlite database looks like this: |collection|key|object|metadata|
To find the number of conversations, or get the userIds for the conversations:
[dbConnection readWithBlock:^(YapCollectionsDatabaseReadTransaction *transaction){
conversationCount = [transaction numberOfCollections];
conversationUserIds = [transaction allCollections];
}];
To get the number of messages in a conversation, or the ids of the messages:
[dbConnection readWithBlock:^(YapCollectionsDatabaseReadTransaction *transaction){
messageCount = [transaction numberOfKeysInCollection:user_id];
messageIdsSorted = [transaction allKeysOrdered:NSOrderedAscending
inCollection:user_id];
}];
To delete old messages from the database:
[dbConnection readWriteWithBlock:^(YapCollectionsDatabaseReadWriteTransaction *transaction){
[transaction removeObjectsEarlierThan:twoWeeksAgo inCollection:user_id];
}];
Hope this helps.
来源:https://stackoverflow.com/questions/15628869/key-value-store-database-on-ios