Database : Account table with Joined Tables Inheritance - database

I have Joined Tables Inheritance in my database : a Client table that can be a Company or a Person. I need to create an account for the client but only one if it's a person and one or many if it's a company. I also have users for backoffice that also need an account. So I tried this but I'm not sure if it's a good idea or not. So is it a good idea or not pls ?
Edited Thanks to The Impaler :
enter image description here

Your model is already pretty good, but you should fix/improve the following issues:
By setting the multiplicity 1 at the sides of Company and Person, the current model states that each client must be associated both with a company and a person! You have to fix this by changing the multiplicity to 0..1 and possibly add an invariant that requires each client to be either a company or a person (in a constraint box attached to the class rectangle).
Since, in general, not every company and not every person is a client, you should either change the multiplicities of their association ends at the Client side to 0..1 or rename these classes/tables to CompanyClient and PrivateClient.
In UML, the names of classes should not be underlined.
In UML, the standard ID attribute(s) of a class (called primary key in databases) have to be desginated by "{id}" appended at the end of the attribute declaration line, and not by underlining the attribute(s) concerned.
It's not good practice in UML, to redundantly represent reference properties both with associations and in the form of attributes, as you do with your #-prefixed attributes. Just drop these non-UML syntax attribute declaration lines.
Better rename your AccountCompany class to AccountsByCompany.

Related

Relational Database: Reusing the same table in a different interpretation

Problem description
I am currently working on a project which requires a relational database for storage.
After thinking about the data and its relations for a while I ran into a quite repetitive problem:
I encountered a common data schema for entity A which contains some fields e.g. name, description, value. This entity is connected with entity B in multiple n-1 relations. So entity B has n entities A in relation rel1 and n entities A in relation rel2.
Now I am trying to break down this datamodel into a schema for a relational database (e.g. Postgres, MySQL).
After some research, I have not really found "the best" solution for this particular problem.
Some similar questions I have found so far:
Stackoverflow
DBA Stackexchange
My ideas
So I have thought about possible solutions which I am going to present here:
1. Duplicate table
The relationship from entity B to entity A has a certain meaning to it. So it is possible to create multiple tables (1 per relationship). This would solve all immediate problems but essentially duplicate the tables which means that changes now have to be reflected to multiple tables (e.g. a new column).
2. Introduce a type column
Instead of multiple relationships, I could just say "Entity B is connected with n entity A". Additionally, I would add a type column that then tells me to which relation entity A belongs. I am not exactly sure how this is represented with common ORMs like Spring-Hibernate and if this introduces additional problems that I am currently unaware of.
3. Abstract the common attributes of entity A
Another option is to create a ADetails entity, which bundles all attributes of entity A.
Then I would create two entities that represent each relationship and which are connected to the ADetails entity in a 1-to-1 relationship. This would solve the interpretation problem of the foreign key but might be too much overhead.
My Question
In the context of a medium-large-sized project, are any of these solutions viable?
Are there certain Cons that rule out one particular approach?
Are there other (better) options I haven't thought about?
I appreciate any help on this matter.
Edit 1 - PPR (Person-Party-Role)
Thanks for the suggestion from AntC. PPR Description
I think the described situation matches my problem.
Let's break it down:
Entity B is an event. There exists only one event for the given participants to make this easier. So the relationship from event to participant is 1-n.
Entity A can be described as Groups, People, Organization but given my situation they all have the same attributes. Hence, splitting them up into separate tables felt like the wrong idea.
To explain the situation with the class diagram:
An Event (Entity B) has a collection of n Groups (Entity A), n People (Entity A) and n Organizations (Entity A).
If I understand correctly the suggestion is the following:
In my case the relationship between Event and Participant is 1-n
The RefRoles table represents the ParticipantType column that descibes to which relationship the Participant belongs (is it a customer or part of the service for the event for example)
Because all my Groups, People and Organizations have the same attributes the only table required at this point is the Participant table
If there are individual attributes in the future I would introduce a new table (e.g. People) that references the Participant in a 1-1 relationship.
If there are multiple tables going to be added, the foreign key of the multiple 1-1 relationship is mutually exclusive (so there can only be one Group/Person/Organization for a participant)
Solution suggested by AntC and Christian Beikov
Splitting up the tables does make sense while keeping the common attributes in one table.
At the moment there are no individual attributes but the type column is not required anymore because the foreign keys can be used to see which relationship the entity belongs to.
I have created a small example for this:
There exist 3 types (previously type column) of people for an event: Staff, VIP, Visitor
The common attributes are mapped in a 1-1-relationship to the person table.
To make it simple: Each Person (Staff, VIP, Visitor) can only participate in one event. (Would be n-m-relationship in a more advanced example)
The database schema would be the following:
This approach is better than the type column in my opinion.
It also solves having to interprete the entity based on its type in the application later on. It is also possible to resolve a type column in an ORM (see this question) but this approach avoids the struggle if the ORM you are using does not support resolving it.
IMO since you already use dedicated terms for these objects, they probably will diverge and splitting up a table afterwards is quite some work, also on the code side, so I would suggest you map dedicated entities/tables from the beginning.

how to check member type when having hierarchical inheritance

I have the following structure :
Person (abstract class) inherited by admin,staff and candidate. The candidate has two subclasses : admitted and retained.
So when a "person" sign in, I have to check if he's admin, staff or candidate, and if he is candidate I have to check if he's admitted,retained or just candidate, that means that I have to check 4 to 6 table each time someone sign in and in addition I will have to make a lot of if else in my program (to create the appropriate instance), I thought to go for a TPH but the problem is that some subclasses have relationships with other classes that some other don't have for example admin have a relation with "Processing result" (he's allowed to consult the processing results, and this will be logged in the database)
So what's the best solution to check member type in this case? is it possible to add a discriminator column in TPT ? can it be a foreign key (like putting all types in a table and put references to this types in the person and candidate table) ?
Thank you :)

When should I put an attribute in a separate table?

When should I put an attribute in a separate table? I mean is I have an attribute but whether I should put this with the rest of the attributes of a table person or whether I should put it in a separate table with person_ID as FK?
Secondly, when does an association class is formed? Can it form between a class and its multivariate attribute? Ex class book has attribute author. An author can write many books and a book can be written by many authors
You should put an attribute in a separate table whenever you expect that one person could have multiple of that attribute. Otherwise, there's not much reason to separate it, and there can be some conceptual overhead in doing so. (It can be very annoying when you have to write a query that retrieves five different attributes of a person, if each attribute is in its own table unnecessarily.)
You should create an association table between two tables whenever the relationship between them is many-to-many. Your author–book example is a good one.
It depends on what that attribute is dependant of. If it's an attribute of that entity you're creating (person) then it should go in the same table, but as you said in the case of a book where 1 book can have many authors and 1 author can write many books, you have to take into consideration the relationship between the entity and the attribute. Is it a 1 to 1 relationship, 1 to many or many to 1, etc.
This being said, if your person can only have 1 value for that attribute and that only 1 person can have that attribute, then it should go in the same table.
You should have an association table in the following situation:
1 person CAN live in more than 1 house at a time, (home and holiday house) but more people CAN also live in those houses.
Obviously, in the example above, we're ignoring the fact that 1 person cannot be in more than 1 place at a time.
As a general rule, the attribute should be dependant on "the key, the whole key and nothing but the key"
UPDATE for what #ruakh said:
It can create overhead if you separate attributes but a tool which you can use to accommodate this overhead is creating Views of the table. I'm not sure what database system you're using but MySQL has this feature. A View is a "virtual" table that you can create using SQL queries on the current database. You can combine multiple tables and you will query that View just as you would do with a normal table.

Cakephp workaround for model inheritance relationship

From my understanding, cakephp doesn't support database inheritance relationship. However, I want to create a database with different type of Users.
In this case, there are three types of Users: Seller, Customer, and Administrator. Every users should have basic User information such as password, username, etc.
However, each types of users will have its own unique set of datas. For example, seller may have inventory_id while customer may have something like delivery_address, etc.
I have been thinking of creating a workaround to this problem without destroying cakephp convention. I was going to create three additional foreign keys, admin_id, seller_id and customer_id, inside User table, which links to other table. However, knowing that this is an IS-A relationship not HAS-A, I would have to make sure that two of the ids are NULL value. Therefore, this workaround seems ugly to me..
Is there any other simpler, better approach?
For this type of database structure I would probably look at adopting an Entity-Attribute-Value model. This would mean your customer may have a delivery_address and your user may have an inventory_id but as far as your relationship in Cake is concerned your both your user and customer would just have an attribute_id ... you can then create another table that stores what type of attributes are available.
It it's simplest form, your user and customer would be attached to an *attribute_lookup* or *attribute_link* table by a hasMany (probably) relationship. That attribute_lookup/link table would be connected by a belongsTo/hasOne relationship to the actual Attribute Type and Attribute Value models.
Providing that you normalise your tables correctly, you can stick well within Cake relationship conventions.
You can read more about EAV here.
I have been thinking about this problem for some time now, and I have eventually got around to build a solution for it. What I came up with is a new ORM that can be used on top of CakePHP.
It sort of works as CakePHP 3.0 with entities that represent an id/model, but it is much more advanced and supports multi table inheritance and single table inheritance.
Check it out: https://github.com/erobwen/Cream

a layman's term for identifying relationship

There are couples of questions around asking for difference / explanation on identifying and non-identifying relationship in relationship database.
My question is, can you think of a simpler term for these jargons? I understand that technical terms have to be specific and unambiguous though. But having an 'alternative name' might help students relate more easily to the concept behind.
We actually want to use a more layman term in our own database modeling tool, so that first-time users without much computer science background could learn faster.
cheers!
I often see child table or dependent table used as a lay term. You could use either of those terms for a table with an identifying relationship
Then say a referencing table is a table with a non-identifying relationship.
For example, PhoneNumbers is a child of Users, because a phone number has an identifying relationship with its user (i.e. the primary key of PhoneNumbers includes a foreign key to the primary key of Users).
Whereas the Users table has a state column that is a foreign key to the States table, making it a non-identifying relationship. So you could say Users references States, but is not a child of it per se.
I think belongs to would be a good name for the identifying relationship.
A "weak entity type" does not have its own key, just a "partial key", so each entity instance of this weak entity type has to belong to some other entity instance so it can be identified, and this is an "identifying relationship". For example, a landlord could have a database with apartments and rooms. A room can be called kitchen or bathroom, and while that name is unique within an apartment, there will be many rooms in the database with the name kitchen, so it is just a partial key. To uniquely identify a room in the database, you need to say that it is the kitchen in this particular apartment. In other words, the rooms belong to apartments.
I'm going to recommend the term "weak entity" from ER modeling.
Some modelers conceptualize the subject matter as being made up of entities and relationships among entities. This gives rise to Entity-Relationship Modeling (ER Modeling). An attribute can be tied to an entity or a relationship, and values stored in the database are instances of attributes.
If you do ER modeling, there is a kind of entity called a "weak entity". Part of the identity of a weak entity is the identity of a stronger entity, to which the weak one belongs.
An example might be an order in an order processing system. Orders are made up of line items, and each line item contains a product-id, a unit-price, and a quantity. But line items don't have an identifying number across all orders. Instead, a line item is identified by {item number, order number}. In other words, a line item can't exist unless it's part of exactly one order. Item number 1 is the first item in whatever order it belongs to, but you need both numbers to identify an item.
It's easy to turn an ER model into a relational model. It's also easy for people who are experts in the data but know nothing about databases to get used to an ER model of the data they understand.
There are other modelers who argue vehemently against the need for ER modeling. I'm not one of them.
Nothing, absolutely nothing in the kind of modeling where one encounters things such as "relationships" (ER, I presume) is "technical", "precise" or "unambiguous". Nor can it be.
A) ER modeling is always and by necessity informal, because it can never be sufficient to capture/express the entire definition of a database.
B) There are so many different ER dialects out there that it is just impossible for all of them to use exactly the same terms with exactly the same meaning. Recently, I even discovered that some UK university that teaches ER modeling, uses the term "entity subtype" for the very same thing that I always used to name "entity supertype", and vice-versa !
One could use connection.
You have Connection between two tables, where the IDs are the same.
That type of thing.
how about
Association
Link
Correlation

Resources