Inherit from SPManagedObject - simperium

In Simperiums iOS/OSX tutorial you say, each modeled object should inherit from SPManagedObject.
I didn't try it yet, but doesn't that lead to one big table in the SQLite database that contains a union of all fields of all modeled managed objects?

Yes, under the hood Core Data will tend to create a bigger table. Generally performance will suffer more from relations though, not inheritance:
Using Parent Entity in CoreData Models
We've done integrations with fairly complex inheritance hierarchies and didn't see any immediate issues with a fair amount of data.
Having said that, should you need more control over your table structure, you can avoid having a single parent for all your objects and instead either:
Manually add the ghostData and simperiumKey attributes to the objects you want to sync, and ensure their class is SPManagedObject (or ensure their custom class inherits from SPManagedObject), or
Create more than one parent entity with ghostData and simperiumKey attributes, and inherit from those for the parts of your model where it makes sense, depending on how you'd like the underlying tables to be structured.

Related

Core Data design principles

I just started reading this guide: https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/KeyConcepts.html#//apple_ref/doc/uid/TP40001075-CH30-SW1
And it basically has (in my opinion) two big contradictions:
I get them both, but basically, if I follow the first "implement a custom class to the entity from which classes representing subentities also inherit"-statement, then ALL my entities will be put in the same table. Which could cause performance issues, according to the NOTE.
How big of a performance hit would I run into of it create a "custom super entity"?
You can use the inheritance mechanism to get a default database structure. From your link:
If you have a number of entities that are similar, you can factor the common properties into a superentity, also known as a parent entity.
There is no contradiction. The documentation is just telling you what the database structure is going to be when you use a certain facility. (And it is the standard database table idiom for inheritance.) Using the entity inheritance mechanism automatically declares and implements default parent-child class inheritance functionality along with a parent table. Otherwise you do any parent-child class inheritance declaration and implementation by hand. Each comes with certain performance and other characteristics.
Design involves tradeoffs between costs and benefits over multiple dimensions. "Performance" itself involves multiple dimensions, and has no meaning outside of given application usage patterns. Other dimensions relevant here include complexity of both construction and maintenance.
If you query about entities as parents sufficiently frequently then it can be better to have all parent data in its own table. But if you sufficiently rarely ask for the parent data while querying about a given child type or if you sufficiently frequently need both child and parent data then it can be better to only have parent data in the child tables or table. But notice that each design performs worse at the other kind of query.
The first is talking about sub-entities. The second is talking about subclasses. These are 2 different hierarchies.
One use for sub-entities is if you have a table where you want to show cells displaying different entities. By making them sub-entities, you can fetch the parent entity and all sub-entities will be returned. This is actually how the Notes app shows the "All Notes" cell above folders, that is actually displaying the Account entity, and both Account and Folder are sub-entities of NoteContainer which is what is fetched. This does mean all of the rows are in the same table, but personally I have not experienced any performance problems but it is something to keep in mind when modifying the entities in other ways like indexes, relations or constraints for example.
I'm not familiar with this quirk of SQLite, but modeling base class/subclass relationships are usually done with different tables. There is one table that represents the base class which contains attributes common to all derivative classes (Vehiclea) and a different table for each subclass which contain attributes unique to that subclass (Cars, Trains, Airplanes).
Performance is no better or worse than any entity normalized across different tables.

Model structure when entities having some properties in common

I have 2 entities in Core Data which have some common properties. I have to show both the entities in a same list view. What will be the best practice to do this? Can I do some inheritance thing and put common properties in base class?
Core Data supports inheritance.
Open your core data model and select the child entity. Make sure the utilities pane is displayed (top right button in Xcode) and select "Show the data model inspector" (right most icon in the utilities pane).
Here you can select a parent entity for your entity. All attributes of the parent will be available in the child entity.
Apple documentation on Core Data inheritance
What will be the best practice to do this?
It depends on what type of entities you need to model. For example, if you have a Cat and a Dog, you should move the attributes in common in a base entity (say Animal or whatever you want). In other words, you should have a reason for doing this, i.e. entities have a sort of relationship each others.
Can I do some inheritance thing and put common properties in base class?
Yes of course. In a model you are allowed to have a sort of inheritance pattern like the following.
where
I would stress two things here.
First, you can make base entity as an Abstract Entity. In this way, you are not allowed to create instances of this entity.
As per the doc.
You can specify that an entity is abstract—that is, that you will not
create any instances of that entity. You typically make an entity
abstract if you have a number of entities that all represent
specializations of (inherit from) a common entity which should not
itself be instantiated. For example, in a drawing application you
might have a Graphic entity that defines attributes for x and y
coordinates, color, and drawing bounds. You never, though, instantiate
a Graphic. Concrete sub-entities of Graphic might be Circle, TextArea, and Line.
Second, under the hood Core Data will create a single table with all the attributes you have inserted. So, if you have a lot attributes, you will have a lot of columns for a table.

core data structure

Im about to add the persistence layer to my application, and i decided to give core data a go. Currently i map all my models to entities, which seems to work quite well. But in my current implementation i use something i call "collections" (of models) for example i have a collection of tile slots in a game.
this SlotsCollection class has methods like findNextInSameRow() findAvailableSlot() etc. What ive done with core data is i have created a Game entity and added a to many relationship to the Slot entity, Is there a way to define a class which the collection of slots should be instantiated with so i can put my logic inside that? Or is there a better way for me to structure things. I guess i could create "managers" inside my Game entity and hand in the slots when initialized
SlotManager* manager = [SlotManager alloc] initWithSlots:self.slots];
Slot* slot = [manager findAvailableSlot];
Also after i "migrated" all my models to entities, i have alot of entities that do not have any attributes but only hold references to other entities. Im abit afraid im using a wrong mindset when structuring the core data.
The class that has the collection should have the logic for that collection.
If you have a 1-to-many relationship from A to B, then you'd put the logic about this relationship into class A — and possibly some of it inside class B (depending on your needs).
Note: If you're iterating through relationships, you need to be aware of faulting behavior etc. Whenever Core Data has to do actual database work, you incur a performance hit. That's no different that plain old SQL. If you don't have to "go to disk" things are very fast. If you're using fetch request you will always do database work, and things will always be (relatively) expensive.

Is it difficult to manage iInheriting a client dataset from another?

Say I have a client dataset CDSPerson that acts as a wrapper around a Persons database table. Say I have another table, PersonBenefits, that joins 1:1 back to the Persons table.
Say I wrap a Delphi class around CDSPerson, PersonClass, and another class around CDSPersonBenefits, PersonBenefitsClass, to read and write records. PersonBenefitsClass inherits from PersonClass so it can provide data from both tables. I'd like to be able to write data back to either table through PersonBenefitsClass.
Has anyone developed a clean way to handle the SQL query, provider flags and commit logic in the inherited class so that (a) fields stay aligned with the parent class and (b) both database tables can be updated?
Is there a reference for this that I can't find? Is this just a bad idea? I'm using Delphi 2007.
If you're going to develop a business-object-to-database mapping framework, (commonly known as ORM, Object-Relational Mapper,) you're going to need to put in a bit of architecture to make relationships like this work properly. Here's one way to do it:
PersonClass and BenefitsClass both inherit from BusinessObjectClass. BusinessObjectClass is a base class that contains the general logic to interact with the dataset. It has a list object of some sort that contains a list of relation objects.
Each relation object is a special object that contains either one or a list of BusinessObjectClass descendants, plus extra data describing the foreign-key relationship between the two tables. When BusinessObjectClass does its queries and its updates, it needs to iterate through all its relation objects and have them do their own queries and updates as appropriate.
In your composite object, (PersonWithBenefitsClass,) in the constructor, call inherited and then set up a relation object that describes the related BenefitsClass. Make sure that any inserts of new objects are done in the right order to preserve referential integrity.
That's the basic idea. (One basic idea. There are probably plenty of other ways to do it.) I'll leave the details of exactly how you implement it up to you.

How to map class hierarchy (base class and inherited classes) to a database

I want to create a hierarchical object model in ASP.NET MVC, but I'm not sure what would be the best way to design database for this. I have a Product base class with certain properties like Title, Price, OnHandQty etc. I have several inherited classes like Book, which has extra properties like ISBN number, Author etc. Many of my products will fall under generic (base) Product class, but some products will fall under these derived classes (e.g. Book). I am not sure what is the best methodology to map this to database. Should I create separate tables for each product type (including one for generic product)? Or is there any better way?
Please note that I'm not really asking about OR mapping. I know how to create classes from DB tables using Entity Framework. But in this case I am confused about the database design itself.
If you are going to use Entity Framework then you should check out Inheritance with EF Code First by mortezam. He explains three strategies that can be used for representing an inheritance hierarchy:
Table per Hierarchy (TPH): Enable
polymorphism by denormalizing the
SQL schema, and utilize a type
discriminator column that holds type
information.
Table per Type (TPT): Represent "is
a" (inheritance) relationships as
"has a" (foreign key) relationships.
Table per Concrete class (TPC):
Discard polymorphism and inheritance
relationships completely from the
SQL schema.
The idea (with Code First) is that you define your classes and inheritance and let the framework create the database for you. That way you don't need to worry so much about the database design.
You might also want to think about using an Object Database or one of the NoSQL storage strategies like Mongo DB which work better than relational databases when you have these kind of 'jagged' classes.

Resources