One To Many Relationship in SQL - 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

Related

What is the point of a junction table

I've been reading up on normalization and relationships and am curious -- is the only point of a junction table to store attributes that don't make sense in either of the parent tables?
For example, if you have a Chat and Users table, and a chat can have many users and visa versa, couldn't you just have a one-to-many relationship on both tables without a junction table?
That is, couldn't you say that a chat has many users and that a user has many chats?
Why would you have to create a table such as ChatUsers and then say that a chats has many chatUsers and that a user has many ChatUsers?
The only reason I can think of is that you want to add attributes like number of undread messages per chat, or notification settings, which only make sense in a ChatUsers table.
If this is not the case, and you don't need to add anything, does the concept of many-to-many even make sense? wouldn't it just be easier to think of it as two one-to-many relationships?
The use of the junction table takes your data to its lowest possible normalised level, it should be used where there is something that could be duplicated across multiple entires such as a date or a time.
I cannot think of a specific example with a Chat and Chat User table, but one ive come across a lot is in relation to addresses.
As individuals both you and myself could live at the same address, but at different times. It wouldnt be appropriate to hold a date of when I lived at an address in a user table (as I could live at multiple addresses). It also wouldnt be appropriate to record a date in the address table (as this could lead to multiple address lines), as such you should end up with tables with the following design and data.
User_Table
User_Id
User_Name
U1
John Smith
U2
Jane Smith
U3
Rebecca Smith
Address_Table
Address_Id
Address
AD1
1 High Street
AD1
2 High Street
AD1
3 High Street
AD1
4 High Street
Address_History_Table
Add_His_ID
User_Id
Address_Id
Start_Date
End_Date
AH1
U1
AD1
01/09/2000
01/01/2019
AH2
U1
AD2
02/01/2019
31/08/2022
AH3
U2
AD1
02/01/2019
AH4
U3
AD2
01/08/1965
31/08/2022
In this example U1 (John Smith) and U2 (Jane Smith) have both lived at address AD1(1 High Street) but not at the same time. In this example Jane moved in (02/01/2019) the day after John moved out (02/01/2019).
U1 (John Smith), then moved into AD2 (2 High Street) from the 02/01/2019 with no end date. U3 (Rebecca Smith) lived in this address already (start_date of 01/08/1965) and lived there until 31/08/2022.
From this we can identify that John and Jane havent lived together, while John and Rebecca did (From the 02/01/2019 to 31/08/2022).
The use of the junction table will very much depend on your data. In your chat example if two users were in the same chat for the exact same time, could lead to a duplication if a time for example was recorded.
A juntion table can sometimes just be three columns
Primary Key of the table
Foreign Key of the user table
Foreign Key of the chat table
The junction table would then just be used to denote which chat linked to which user, and dosent need to contain any other 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.

What if your fact has multiple instances of the dimension?

In a star schema for a clothes shop, there is a transaction fact to capture everything bought. This will usually have the usual date, time, amount dimensions but it will also have a person to indicate who bought it. In certain cases you can have multiple people on the same transaction. How is that modelled if the foreign key is on the Fact table and hence can only point to one Person?
The standard technique in dimensional modelling is to use a 'Bridge' table.
The classic examples you'll find are groups of customers having accounts (or transactions), and for patients having multiple diagnoses when visiting a hospital.
In your case this might look like:
Table: FactTransaction
PersonGroupKey
Other FactTableColumns
Table: BridgePersonGroup
PersonGroupKey
PersonKey
Table: DimPerson
PersonKey
Other person columns
For each group of people you'd create a new PersonGroupKey and end up with rows like this:
PersonGroupKey 1, PersonKey 5
PersonGroupKey 1, PersonKey 3
PersonGroupKey 2, PersonKey 1
PersonGroupKey 3, PersonKey 6
PersonGroupKey then represents the group of people in the Fact.
Logically speaking, there should be a further table, DimPersonGroup, which just lists the PersonGroupKeys, but most databases don't require this so typically Kimball modellers do away with it.
That's the basics of the Bridge table, but you might consider modifications depending on your situation!
You need a joining table TransactionPerson (or something like that), where Person to TransactionPerson is 1:M relationship and then TransactionPerson to Transaction is M:1 relationship.
That way you can have multiple people relating to one transaction indirectly.
I would propose to use a Bridge table in combination with your transaction and person tables. Ex:
Table: fact_transaction
transaction_id (primary key)
transaction_person_id (foreign key)
...
Table: bridge_transaction_person
transaction_person_id
person_id
Table: dim_person
person_id (primary key)
...

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.

Entity Relation Abiguity

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)