I am currently in the process of migrating from CoreData to Realm (Sync). I could need some help with the partitioning strategy. My app has (currently) basically two types of data, either publicly available data (generated by me) or user-specific data (generated and only readable by the user). Therefore, I was planning to establish the partition value to be either "public" for public data or "user=<user_id>" for user-specific data.
The thing is, that I need to establish relationships between public and private objects (e.g. a public exercise can be part of a private workout routine), which, if I understand correctly, is not possible in Realm.
In addition, I need to query all objects of a type (private and public) to present the objects in a table (sorted alphabetically), which I find quite hard, since I would need to somehow combine the Realm Results.
To solve this issue I can imagine two strategies:
Duplicate the “public” data to each for each user, so that the data is synced with the user`s partition, however, ending in overload of storage.
Manage the relationships on the client side manually (e.g. by referencing only the object id), which I would like to avoid… (and which would only solve the relationship problem)
Do I understand the issue correctly? And if yes, can it be solved better?
The question is clear but some details would help.
In this use case, what is the relationship between the user object (with partitonKey = userId) and the public object (with partitionKey = “public”). e,g, can you provide those objects (shortened for brevity) so we can see how the relationship is set up?
Denormalizing data is quite normal on NoSQL databases (Atlas) - while it is “more data” stored, since the exercises are duplicated, how much data are we talking about? is it a few dozen bytes or Mb or what?
Have you considered doing some server side processing to get to the data you want as it is possible in that environment, just not on the client side. (again, need to see how that relationship is built)
Have you considered creating a Realm with partitionKey = “workouts” and have the public workouts and user workouts sharing the same partitionKey? That would allow each persons workouts tied to the person via their uid and also tied the workout template it comes from? You could then have all of the workout data within one realm.
class UserWorkoutClass: Object { //Swift object example @objc dynamic var partitonKey = “workouts” @objc dynamic var user_id = uid //points to the user @objc dynamic var workout_template = //points to the workout template this comes from @objc dynamic var workout_name = “This users workout #1 /flex”
}
@Dominik_Hait I would use manual references, analogous to a foreign key relationship, to create references across Realm files. For combining the two different queries into a single result bound to the UI what you can do is copy the data out of the Realms and use in-memory objects to create your own results which then get bound to the UI. We are working on a feature called Projections which will help in this use case - essentially help to abstract away the boilerplate in a ViewModel - you can learn more about this here:
This Projections project is currently in development and will not be delivered for over a quarter so its still a ways out.
Of course, to Jay’s point you could denormalize the public data and copy it into every user’s partition - it really depends on the amount of data whether this is a feasible option or not. This would avoid both the issues you had flagged.