yapstudios / YapDatabase

YapDB is a collection/key/value store with a plugin architecture. It's built atop sqlite, for Swift & objective-c developers.
Other
3.35k stars 365 forks source link

Q: DB Architecture Question / Reorderable Views #540

Closed mickeyl closed 3 years ago

mickeyl commented 3 years ago

This is probably more a question of general database design than for YapDatabase, but still: How would you go about implementing a, say, reorderable playlist of songs. The songs are individual model files, the playlists as well. Both go into the database. A playlist can contain any number of songs and a song can be part of multiple playlists.

I'm using the relationship extension to model the is-part-of relation and the auto-deletion. Filtered views take care about showing the entries that belong to single playlists. Users can resort the songs in the playlist though. How would I model that? Do I need to store the order in the playlist model (e.g. by using an array of DBKeys) or is there a more natural place "within" the database?

robbiehanson commented 3 years ago

You might want to use a ManualView.

It's like you said, you need to store the order somewhere. You can simply store the order in the Playlist object itself. But that also implies that the entire playlist object has to be rewritten every time the order changes (item added, removed, or order change). Plus the entire serialized playlist will have to be read from disk in order to get simple info about the playlist, such as its name.

Alternatively, you could have a separate PlaylistOrder object. Which helps with one of the above problems, but not the other.

The ManualView is perhaps the optimal way. Every item in YapDB has a row_id: Int64 (courtesy of sqlite). Internally, the ManualView stores your order by storing an array of those row_id's. And it does so in groups of 50. So a playlist of 150 items is only a few rows in the database, with minimal size. And there are various optimizations that allow the group size to expand beyond 50 to prevent cascading rewrites.