Entity Relation Abiguity - sql

I'm learning about entity relation diagrams (ER) and have a question regarding this. Say I had the following situation "A student can take multiple classes, but doesn't necessarily have to take any".
I'd have a set "student" (S) and a set "classes" (C). Say I want to define a relation "takes". I assume the relation "takes" would be many-to-many with partial participation. That is because a student can take multiple classes, and a class can be taken by multiple people. "Partial" because it could be that there are students who take no classes, and classes who are taken by no student. Is that correct?
Now, assuming I had a set "people" (p) and wanted to define the relation "isChildOfMother". I believe this is many-to-one? Because multiple people can have the same mother, but not multiple mothers, and one mother can have multiple children? But in this case, the relation would be pointing from set p to set p? How can I ensure it's read the right way? (Ie: Not in terms of one child can have multiple mothers but one mother can only have one child?")
I suppose the alternative would be creating a set "children" and a set "mothers", but what if somebody was a mother AND a child?

You can have a self-relationship or recursive relationship
In this case
Each person can have only one mother or no mother.
Ana doesnt have mother (orphan) or the mother isn't on the db.
Ana can have more than one children
Alice is mother and child
Person
id | name | mother_id |
1 | Ana | null
2 | Luis | 1
3 | Alice | 1
4 | Jhon | 3
For this you say mother_id is FK to Person(id)

Related

Structure for 3 or more tables with relationship

I need help about database structure,
so I need to join 3 tables but I'm confuse what structure is the right way.
Region_table
id region_name
1 Region1
2 Region2
Province
id province_name
1 Province1
City
id city_name
1 city1
I'm thinking to create new table that connects all.
like id, region_id, province_id, city_id
region_province_city
id region_id province_id city_id
1 1 1 1
2 1 1 2
or I can do like
Province
id province_name region_id
1 Province1 1
City
id city_name province_id
1 city1 1
I would generally suggest the hierarchical structure. That is, adding the parent id to each of the two tables.
Why? This guarantees that the region on a given province is always the same. That can be hard to guarantee in the 3-way junction table. After all, you don't have an independent relationship among the three entities. You have a hierarchical relationship and you would like to enforce that data integrity.
An example of an independent relationship would be:
Customers
Items
Payment Method
Presumably a customer could purchase any item using any payment method -- and even use different payment methods on the same item.
Would I always recommend this structure? Well, no. If the data is not being modified, then you are pretty safe with the three-way table. It works very well for looking up information about a "city". It can be verified when created. And it might provide some simplification (particularly if the hierarchies are deeper).
That said, it works best when your joins are to the lowest level. It is a little tricky to get the region for a province. A typical solution would be to augment the data with NULL values for city to get that information.

Can somebody give a practical example of a many to many relationship?

I learned about many-to-many relationships in College, and I never really understood them. So far I've been working with one-to-many relationships which are easy to understand and deal with.
Can somebody please give a practical example of a many-to-many relationship, and explain why we need a bridging table for it. Plus, do you need a bridging table for a one-to-many relationship as well? As far as I understand you don't need a bridging table for it, but a friend of mine recently told me otherwise.
One-to-many & many-to-many relationships are not the property of the data rather the relationship itself. And yes you do need bridging/third table for many-to-many relationship in perfect normalized RDBMS world. Lets see each of it with real life example:
One-to-many relationship: When one row of table A can be linked to one or more rows of table B.
Real Life Example: A car manufacturer makes multiple models of the cars, but a same car model can't be manufactured by two manufacturers.
Data Model:
Many-to-many relationship: When one row of table A can be linked to one or more rows of table B, and vice-versa.
Real Life Example: A user can belong to multiple community, and a community can have multiple users.
Data Model:
A practical example to many-to-many is the courses taken in a college. You might have a Courses table like:
CourseId | CourseName
=====================
1 | Algebra 101
2 | Intro to Calculus
3 | Advanced C++
4 | Go Programming
...
And there are Students:
StudentId | Name
===========================
1 | John Doe
2 | Frank Smith
3 | Mary Brown
...
Now, if you think of it, a Student can take multiple (many) Courses and a Course can have many attendant Students. That constitutes a Students(many)-to-(many)Courses relation. There is no way to directly express this without a bridge table (I am lying here but accept there is not), so you create intermediate 3rd table:
Students_Courses
StudentID | CourseID
====================
1 | 1
1 | 3
2 | 2
2 | 4
2 | 1
3 | 2
3 | 4
We are saying:
John Doe (1) is taking (Algebra 101 and Advanced C++),
Frank Smith (2) is taking (Algebra 101, Intro to Calculus and Go Programming)
Mary Brown (3) is taking (Intro to Calculus and Go Programming)
This is like 1-To-Many looking from Students' perspective. We can also look from Courses' perspective:
Algebra 101 members are (John Doe and Frank Smith)
Intro to Calculus members (Frank Smith and Mary Brown)
Advance C++ members (John Doe)
Go Programming (Frank Smith and Mary Brown)
making another 1-To-Many from the other side.
IOW it looks like:
Student +-< Courses and Students >-+ Course
Courses >-< Students
A Many-to-Many bridging table doesn't need to only have IDs from two tables. It is what you need at least but may have other columns if you need like:
StudentId | CourseID | RegistrationDate | CompletionScore
=========================================================
1 | 1 | 2017/02/15 | A+
1 | 3 | 2017/04/07 | NULL
And 1-To-Many tables DO NOT have a bridging table. A typical example is Customers and Orders. A Customer can have (many) Orders but an Order belongs to a single (one) Customer. Orders table itself directly has a foreign key (CustomerId) pointing to its belonging Customer so there is no bridge table.
Note: These are in context of the traditional RDBMS. A many-to-many might be expressed without a bridging table but at this point I would assume that as advanced topic.
This question is old, but a practical example would be found in social networks like Instagram:
You (the follower) follow a person A (the followee).
You also follow person B, person C, etc..., but you are not the only one who may follow person A, as well as not the only one who may follow person B, person C, etc... Your friend or other people may as well follow them too.
So you end up with data shaped in the following way:
Follower | Followee
--------------|--------------
... | ...
You | A
You | B
You | C
Your friend | A
Your friend | B
Your friend | C
... | ...
Which is what you call a bridging table (aka lookup table), describing a many-to-many relationship.
Continuing with the social network example, you need a many-to-many bridging/lookup table otherwise you would have to introduce redundancy in your users table, because you would need to duplicate your You record and that of your friend (Your friend) for each of your followees (A, B, C), which is of course non-practical and violates normalization.
do you need a bridging table for a one to many relationships as well ? As far as I understand you don't need a bridging table for a one to many relationship, but a friend of mine recently told me otherwise.
You may use a bridging/lookup table for a one-to-many relationship for flexibility purposes when e.g. you don't know in advance if the relationship of your data is effectively many-to-many or the relationship is one-to-many but you think that it can evolve and become many-to-many in the future.

Database table design approach

I have a question about proper table design. Imagine the situation:
You have two entities in the table (Company and Actor).
Actor could have several types (i.e. Shop, PoS, Individual etc.)
The relation between entities is many-to-many because one Actor can be assigned to multiple Companies and vice-versa (one Company can have multiple Actors)
To outline this relation, I can create a linking table called 'C2A' for instance. So, we'll end up with the structure like this:
| Company1 | Actor1(Shop)
| Company1 | Actor2(PoS)
| Company2 | Actor1(PoS)
etc.
This approach works just fine until requirement changes. Now we need to have a possibility to assign Actor to an Actor to build another sort of hierarchy, i.e. one Actor (Shop) might have multiple other Actors (PoS's) assigned to it and all this belong to a certain company. So, we'll end up with the structure like this:
| Company1 | Actor1(Shop) | NULL
| NULL | Actor1(Shop) | Actor1(PoS)
| NULL | Actor1(Shop) | Actor2(PoS)
etc.
I need to be able to express relations (between Company (C) and Actor(A)) like this: C - A - A; A - C - A; A - A - C
Having two similar fields in one table is not the best idea. How are the relationships like this normally designed?
Create two separate tables for entities Company and Actors.
Company( Id (PK), Name)
Actor(Id (PK), Name)
Now, if you are sure about many-many. You can go ahead with creating a separate table for this.
CompanyActorMap( MapId (PK), CompanyId (FK), ActorId (FK))
For Actor Heirarchy, use a separate table as it has nothing to do with how the hierarchy is related to the company, its about how the Actors are related to each other. Best approach for multiple level infinite hierarchy is to create a new table with two columns for Actor Id as Foreign Key
ActorHierarchy( HierarchyId (PK), ChildActorId (FK), ParentActorId(FK))
For an Actor that has no parent in hierarchy, there can be an entry in CompanyActorMap table denoting the head of hierarchy and the remaining chain can be derived from the ActorHierarchy table by checking the PArentActorId column and its childActorId.
This is obviously a rough draft. Hope this helps.

One To Many Relationship in SQL

I am trying to understand "one to many relationships". Let's assume I have two tables: Person and Vehicle.
In the Person table, I have 2 columns: personid and personame. personid is the primary key. I have 2 rows in the Person table:
personid | personname
---------+-----------
1 | Rajesh
2 | Suresh
In the Vehicle table, I have 2 columns: vehicleid and vehiclename. I have one row in the Vehicle table
vehicleid | vehiclename
----------+------------
1 | Car
Now, as per "one to many relationships" each person can have zero, one, or many vehicles.
So, can both Rajesh and Suresh be mapped to Car?
For example:
Rajesh -+- Car
Suresh -/
In "one to many relationships", can 2 different Persons refer to the same Vehicle? Or should each Vehicle only be mapped to a single Person?
In "many to one relationships", the only car in the Vehicle table can be mapped to multiple persons in the Person table, correct?
You need a Many-to-many "relationship". It's actually a combination of 2-One-to-many relationships. The only way to do this in sql, is to have a third table.
Person
PersonID
Name
One - to - many (One person can own many vehicles)
Ownership (Or Title?)
PersonID
VehicleID
many-to-one (vehicle can have many owners)
Vehicle
vehicleid
vehiclename
The ownership table has a potential row for any user / vehicle combination (And should probably make that combination a primary key or at least a unique constraint).
Other fields can be put in the ownership table such as purchase date and amount, sale date and amount, etc. Because those pertain to the ownership of the vehicle and not a property of the owner or vehicle itself.
Your question is inconsistent, you say "each person can have zero, one or many vehciles", but then you ask "now can both Rajesh and Suresh be mapped to Car ?", which implies each vehicle can have multiple Owners, not that each person can have multiple vehicles...
Assuming to want to restrict ownership of each vehicle to a single person (In practice, a vehicle can be owned by multiple individuals), and allow an individual to own multiple cars, simply add a PersonId to vehicle table, to indicate or point to the individual who owns that vehicle.
So your vehicle table would then be
vehicleid OwnerId vehiclename
1 1 'Ford'
2 1 'Maserati'
3 1 'BMW'
If Rajesh and Suresh both have the same vehicle and each of them can possibly have more than 1 vehicle, then you have a Many-to-Many Relationship.
But if a vehicle can only be owned by one person, then you have a One-To-Many Relationship from Person to Vehicle.
In One to Many relationship can 2 different persons refer to the car
in vehicle table
no. 2 is not One.
From the Vehicle perspective, it has 1 (one row, the "Car Row") to Many Person rows (assuming Person table had a VehicleId column)
Many to One vs One to Many refers to the same concept, just viewed from different sides. (either from vehicle or person).
In a standard One To Many here you would have
A person table and a vehicle table where the vehicle table contains a personId with a FK to the person table. This will let you model a person with 0 or many vehicles owned by a single person uniquely.
If a vehicle has multiple owners you should introduce a many to many relationship between person and vehicle. That would require a third table (PersonVehicle)
In your example Rajesh and Suresh can share a same car to do this you need car primary key in person table.
Rajesh has one relationship with CarA
Suresh has one relationship with CarA
And CarA will have many relationship(Rajesh & Suresh).
Now, as per "one to many relationships" each person can have zero,
one, or many vehicles.
Correct.
So, can both Rajesh and Suresh be mapped to Car?
No, not in a "one to many relationship". This would be a "many to many relationship".
In "one to many relationships", can 2 different Persons refer to the
same Vehicle? Or should each Vehicle only be mapped to a single
Person?
Each Vehicle should only be linked to a single Person.
In "many to one relationships", the only car in the Vehicle table
can be mapped to multiple persons in the Person table, correct?
Yes, but each Person would then only be able to be linked to a single Vehicle.
"Many to one" and "one to many" are the same thing, just in reverse. So, the following two statements are equivalent:
One A can link to many Bs.
Many Bs can link to one A.
Notice how "one to many" and "many to one" are in each (bold), and how, in order to mean the same thing, the tables A and B are switched?
Examples
Assuming the following:
Person Vehicle
------ -------
Jane Car
John Truck
One to one
Jane is linked to Car. Each Person can only be linked to one Vehicle at a time, and vice-versa.
Jane--------Car
John Truck
One to many
Jane is linked to Car and Truck. Each Vehicle can only be linked to one Person at a time. Each Person can be linked to multiple Vehicles.
Jane---+----Car
John \---Truck
Many to one
Jane and John are linked to Car. Each Person can only be linked to one Vehicle at a time. Each Vehicle can be linked to multiple Persons.
Jane----+---Car
John---/ Truck
Many to many
Each Vehicle can be linked to multiple Persons, and vice-versa.
Jane and John are both linked to Car and Truck.
Jane---+--+-Car
\/
/\
John---+--+-Truck
Jane is linked to Car and Truck, and John is linked to Truck
Jane---+----Car
\
John-----+--Truck

What is the best way to design this particular database/SQL issue?

Here's a tricky normalization/SQL/Database Design question that has been puzzling us. I hope I can state it correctly.
You have a set of activities. They are things that need to be done -- a glorified TODO list. Any given activity can be assigned to an employee.
Every activity also has an enitity for whom the activity is to be performed. Those activities are either a Contact (person) or a Customer (business). Each activity will then have either a Contact or a Customer for whom the activity will be done. For instance, the activity might be "Send a thank you card to Spacely Sprockets (a customer)" or "Send marketing literature to Tony Almeida (a Contact)".
From that structure, we then need to be able to query to find all the activities a given employee has to do, listing them in a single relation that would be something like this in it simplest form:
-----------------------------------------------------
| Activity | Description | Recipient of Activity |
-----------------------------------------------------
The idea here is to avoid having two columns for Contact and Customer with one of them null.
I hope I've described this correctly, as this isn't as obvious as it might seem at first glance.
So the question is: What is the "right" design for the database and how would you query it to get the information asked for?
It sounds like a basic many-to-many relationship and I'd model it as such.
The "right" design for this database is to have one column for each, which you say you are trying to avoid. This allows for a proper foreign key relationship to be defined between those two columns and their respective tables. Using the same column for a key that refers to two different tables will make queries ugly and you can't enforce referential integrity.
Activities table should have foreign keys ContactID, CustomerID
To show activities for employee:
SELECT ActivityName, ActivityDescription, CASE WHEN a.ContactID IS NOT NULL THEN cn.ContactName ELSE cu.CustomerName END AS Recipient
FROM activity a
LEFT JOIN contacts cn ON a.ContactID=cn.ContactID
LEFT JOIN customers cu ON a.CustomerID=cu.CustomerID
It's not clear to me why you are defining Customers and Contacts as separate entities, when they seem to be versions of the same entity. It seems to me that Customers are Contacts with additional information. If at all possible, I'd create one table of Contacts and then mark the ones that are Customers either with a field in that table, or by adding their ids to a table Customers that has the extended singleton customer information in it.
If you can't do that (because this is being built on top of an existing system the design of which is fixed) then you have several choices. None of the choices are good because they can't really work around the original flaw, which is storing Customers and Contacts separately.
Use two columns, one NULL, to allow referential integrity to work.
Build an intermediate table ActivityContacts with its own PK and two columns, one NULL, to point to the Customer or Contact. This allows you to build a "clean" Activity system, but pushes the ugliness into that intermediate table. (It does provide a possible benefit, which is that it allows you to limit the target of activities to people added to the intermediate table, if that's an advantage to you).
Carry the original design flaw into the Activities system and (I'm biting my tongue here) have parallel ContactActivity and CustomerActivity tables. To find all of an employee's assigned tasks, UNION those two tables together into one in a VIEW. This allows you to maintain referential integrity, does not require NULL columns, and provides you with a source from which to get your reports.
Here is my stab at it:
Basically you need activities to be associated to 1 (contact or Customer) and 1 employee that is to be a responsible person for the activity. Note you can handle referential constraint in a model like this.
Also note I added a businessEntity table that connects all People and places. (sometimes useful but not necessary). The reason for putting the businessEntity table is you could simple reference the ResponsiblePerson and the Recipient on the activity to the businessEntity and now you can have activities preformed and received by any and all people or places.
If I've read the case right, Recipients is a generalization of Customers and Contacts.
The gen-spec design pattern is well understood.
Data modeling question
You would have something like follows:
Activity | Description | Recipient Type
Where Recipient Type is one of Contact or Customer
You would then execute a SQL select statement as follows:
Select * from table where Recipient_Type = 'Contact';
I realize there needs to be more information.
We will need an additional table that is representative of Recipients(Contacts and Customers):
This table should look as follows:
ID | Name| Recipient Type
Recipient Type will be a key reference to the table initially mentioned earlier in this post. Of course there will need to be work done to handle cascades across these tables, mostly on updates and deletes. So to quickly recap:
Recipients.Recipient_Type is a FK to Table.Recipient_Type

			
				
[ActivityRecipientRecipientType]
ActivityId
RecipientId
RecipientTypeCode
||| ||| |||_____________________________
| | |
| -------------------- |
| | |
[Activity] [Recipient] [RecipientType]
ActivityId RecipientId RecipientTypeCode
ActivityDescription RecipientName RecipeintTypeName
select
[Activity].ActivityDescription
, [Recipient].RecipientName
from
[Activity]
join [ActivityRecipientRecipientType] on [Activity].ActivityId = [ActivityRecipientRecipientType].ActivityId
join [Recipient] on [ActivityRecipientRecipientType].RecipientId = [Recipient].RecipientId
join [RecipientType] on [ActivityRecipientRecipientType].RecipientTypeCode = [RecipientType].RecipientTypeCode
where [RecipientType].RecipientTypeName = 'Contact'
Actions
Activity_ID | Description | Recipient ID
-------------------------------------
11 | Don't ask questions | 0
12 | Be cool | 1
Activities
ID | Description
----------------
11 | Shoot
12 | Ask out
People
ID | Type | email | phone | GPS |....
-------------------------------------
0 | Troll | troll#hotmail.com | 232323 | null | ...
1 | hottie | hottie#hotmail.com | 2341241 | null | ...
select at.description,a.description, p.* from Activities at, Actions a, People p
where a."Recipient ID" = p.ID
and at.ID=a.activity_id
result:
Shoot | Don't ask questions | 0 | Troll | troll#hotmail.com | 232323 | null | ...
Ask out | Be cool | 1 | hottie | hottie#hotmail.com | 2341241 |null | ...
Model another Entity: ActivityRecipient, which will be inherited by ActivityRecipientContact and ActivityRecipientCustomer, which will hold the proper Customer/Contact ID.
The corresponding tables will be:
Table: Activities(...., RecipientID)
Table: ActivityRecipients(RecipientID, RecipientType)
Table: ActivityRecipientContacts(RecipientID, ContactId, ...,ExtraContactInfo...)
Table: ActivityRecipientCustomers(RecipentID, CustomerId, ...,ExtraCustomerInfo...)
This way you can also have different other columns for each recipient type
I would revise that definition of Customer and Contact. A customer can be either an person or a business, right? In Brazil, there's the terms 'pessoa jurídica' and 'pessoa física' - which in a direct (and mindless) translation become 'legal person' (business) and 'physical person' (individual). A better translation was suggested by Google: 'legal entity' and 'individual'.
So, we get an person table and have an 'LegalEntity' and 'Individual' tables (if there's enough attributes to justify it - here there's plenty). And the receiver become an FK to Person table.
And where has gone the contacts? They become an table that links to person. Since a contact is a person that is contact of another person (example: my wife is my registered contact to some companies I'm customer). People can have contacts.
Note: I used the word 'Person' but you can call it 'Customer' to name that base table.