Many to many relationship with several tables - sql

I have the following tables
Company:
Id,Name
Person:
Id,Name
A company can have one or more directors. A director can be either another company or a person.
To link them I have a table Director:
Director: Id,CompanyId,DirectorCompanyId,PersonId
where if a company is a director DirectorCompanyId has a value and PersonId is null or if a Person is a director PersonId has a value and DirectorCompanyId is null
But I feel like this is not a correct design.

You're right, it's not a correct design. To decompose a M:M relationship into two 1:M relationships you need a third table:
CompanyPerson
--these columns are vital to decompose the many:many relationship
--the PK of this table should be a compound of these two columns
--so that the same person cannot twice work for the same company
--with different roles etc
PersonID -> FK to Person.ID
CompanyID -> FK to Company.ID
--plus other properties like:
RoleID -> FK to Role table --if roles are a defined set of options
StartDate -> --when the person began this employment
ManagerPersonId -> --the person's mananger.. etc
PersonID + CompanyID is the composite primary key for this table
It maps people to companies and the role they have at each. Can also have other info like start date, manager at that Company etc.. (might also need to make start date part of primary key if a person will ever leave and come back to the same co, and you wanted to recycle the PersonID)
Note: You could call this table Employee, because that's effectively what the people inside it are, but I tend to find it more helpful that these middle-man tables that create associations between two other tables are better off called Table1Table2 because you can more clearly see/understand the relationship/purpose of the table than if it's called something more abstract like Employee

The following design seems to be corresponding to demands
Another option is to use inheritance:
Director <-- CompanyDirector
<-- PersonDirector

Related

How to implement ER Relationships :One to one, One To Many, Many to Many in Oracle?

Perhaps, this could seem like the basics of database design.But,certainly i find these concepts a lil tricky in the sense that how they relate to each other.
Theory as per my understanding.
One to One :
When each particular entity has one record.
One to Many :
When each particular entity has many record
Many to Many :
Multiple entities have multiple records.
As per the above if i could relate an example as
ONE TO ONE
Each employee having a unique passport number.
Table Employee
Empid(pk)
empname
passpordid(fk to passport)
Table passport
passportid(pk)
passportno
ONE TO MANY
An organisation having multiple employees
TABLE ORGANISATION
ORGID (PK)
ORGNAME
EMPID (FK TO EMPLOYEE)
TABLE EMPLOYEE
EMPID (PK)
EMPNAME
SALARY
This is the part that i want to know more that is many to many. I mean if we see one to many here. As a whole it could be said as many to many as many organisations having many employees but does that mean the whole relationship is many to many not one to many or one to many is a subset of many to many in the above example.
I wanna know the difference mainly between one to many and many to many both theoritically and by implementation.
An example of a many-to-many relationship would be EMPLOYEES and SKILLS, where SKILLS are things like "SQL", "Javascript", "Management" etc. An employee may have many skills (e.g. may know SQL and Javascript), and a particular skill by be possessed by many employees (e.g. Jack and Jill both know SQL).
In a database like Oracle, you need a third table to express the many-to-many relationship between EMPLOYEES and SKILLS:
create table EMPLOYEE_SKILLS
( empid references EMPLOYEES
, skillid references SKILLS
, constraint EMPLOYEE_SKILLS_PK primary key (empid, skillid)
);
Note that this third table has a foreign key to both of the other tables.
The table can also hold further information about the relationship - for example:
create table EMPLOYEE_SKILLS
( empid references EMPLOYEES
, skillid references SKILLS
, rating number
, date_certified date
, constraint EMPLOYEE_SKILLS_PK primary key (empid, skillid)
);
This is more a theory question that a programming one, but why not.
You could imagine a "many to many" as 1 table being a list of employees, and another table being a list of products sold.
Each employee is likely to "handle" more than 1 product, and each product could very well be handled by multiple employees, and it's quite possible that products A and B can be handled by, at the same time, employees C and D.
You seem to have the basic idea of one-to-one and one-to many down, in theory.
One-to-one: each item A has a separate and unique item B
In a database, you could include the new data in the same table. You could put it in a separate table, and enforce the one-to-one constraint by making the id into the remote table "unique" (indexing constraint), forcing the id for item B to not be repeated in the table. In your example, this would be a constraint added to the passportid.
One to many: each item A has some number of item Bs
In a database, you put the key in the table on the "many" side. So many Bs would have the same foreign key into table A. In your example, put an orgid as a foireign key into the employee table. Many employees can then point to a single organization, and an employee can belong to one organization.
Many to many: some number of As can be linked to any number of Bs and vice-versa
In a database, this is usually implemented as a link table, having just the IDs from both A and B. Following you example, consider that an employee can be part of multiple groups (or projects), multitasking across those groups. You could have a group table:
GROUPID (PK)
GROUPNAME
And the link table would then look like
LINKID (PK)
EMPID (FK TO EMPLOYEE)
GROUPID (FK TO GROUP)
This lets any employee be part of any number of groups, and groups to have any number of employees, AKA many-to-many.
A side comment:
Technically, you don't HAVE to have a LINKID in the link table. But it makes it easier to manage the data in that table, and is generally considered "best practice".

sql primary key "mapping table ?"

i have a database for university so the students take many courses but each student have id as primary key also each course have an id as primary key its not allowed to have duplicate id at same table what should i use to make a table that same id but different courses id
In a normalized relational database, when you have a situation where items from one table can be associated with many items in a second table, and likewise those related items can be associated with many items in the first table, you should use a third table to store those relationships. In your case, that table might be called Enrollments.
You can use JOIN operations on that third table to relate, group, and aggregate across that relationship. You can also store any metadata associated with that relationship in the JOIN- table, for example you might store the enrollment date there.
Like vicatcu said, create a third table
Course_id | Student_id
The ID's of the courses and the students are uniq in their own tables. The relation between course < - > student is stored in that third table.

The correct database schema for one-to-many relationship

I’m building a hobby site about cars. If a user clicks on a car I want to display a list of similar cars for the chosen car.
I have a main table witch stores the basic information about each car, CarDataMain, two of the columns in the table are CarID (Pk) and SimilarCarsID (Fk).
I have another table called “SimilarCars”, it has three columns; SimilarCarsID (Pk), CarGroupID and CarID.
So the SimilarCarsID-column in the SimilarCars-table has a relationship with the column SimilarCarsID in the CarDataMain-table.
Is this the correct approach, or “best practice”?
Each car can only belong to one CarGroup (CarGroupID).
Another solution would be to create a third table witch holds the relationship between CarDataMain and SimilarCars-data, but as there is a one-to-many relationship I guess this is over kill? That way I could however put the same foreign key-value in CarDataMain for all cars witch belong to the same CarGroup, witch somehow feels appealing…
A third solution would be to skip the SimilarCarsID column in CarDataMain and make the CarID a foreign key in the SimilarCars table, if you understand what I mean. But I guess there are some drawbacks with that solution…
Sorry for newbie questions (and if this question has been up before), but I want to get it right before I start :)
Ludde
Note: re-written
Design tables that describe things like Car, Group, others?
Use "join tables" to give the desired one-to-many relationships.
Tables
CarID - primary key
Group
GroupID - primary key.
Name - the name of the group.
The GroupID may not be necessary. If Name is unique then use that as the primary key.
CarGroup
CarID - foreign key to Car Table
GroupID - foreign key to Group table
This is a join table. Here you can map a given car to many groups, and map a given group to many cars.
SimilarCar
I may be misunderstanding, but is seems like you want to match cars as similar, for no particular reason. If you want to match by group, that is above; and if you want "these 2 cars are similar, period", here you go. This is not mutually exclusive to the groups.
CarID - FK to Car table
SimilarCarID - Fk to Car table
A constraint so CarId cannot match SimilarCarID -- unless you do want a car to be similar to itself. But if so then just read the car table instead.
I think your concepts need to be cleared up first. Isn't a "similar car" a car that is in the same "group"? If so, you only need 1 term. Since "group" is a reserved word it is better to use something else.
I would go with the term "category". So my Cars table would have a CategoryId column. Picture the page on the front-end where someone would add a new car, wouldn't they have a drop down list to select the Category?
So my model would be:
Cars
-Id (PK)
-Name
-CategoryId (FK to Categories)
...
Categories
-Id (PK)
-Name

How to model many-to-many relationships in SQL?

I have a major problem with my SQL design.
I need to create a database which models the following situation:
I have a list of capitals, it looks like this: Berlin, London, Prague, you get it. The other list is a list of travellers: John, Kyle, Peter etc.
The database needs to be able to answer queries such as: List of cities a given Traveller has visited, what Travellers has visited a given City and so on.
My problem is that when I create the two tables I just freeze and am unable to figure out the connection between them that would allow me to implement the intended behaviour.
I read up on it on the internet and I was told to use intersection entities, which I can, but I just don't see how that would help me. Sorry if this is a FAQ, but I just could not get my head around the proper keywords for a search.
Isn't it easier to create third table like travelers_cities with to foreign keys traveler and city, than you jan join that table with table you need and look for result there?
Solution:
Follow the following schema
First Table: Capital
Let say two columns: cid (Primary Key), Name
Second Table: Travellers
Let say two columns: tid (Primary Key), Traveller_Name
Now there is a many to many relationship that one traveller can travel/visit one or many capitals and one capital can be visited by one or many visitors.
Many to many relationship can be acheived by creating a new table which will act as reference/mapping table. let say "capital_travellers"
So, This third table will have following columns
capital_travellers:
id (Primary key): Its optional
cid (Primary key of Capital Table will work as Foreign key)
tid (Primary key of traveller Table will work as Foreign key)
Now when you want to fetch records, you will look into this table(capital_travellers).
I hope it helps.
In a many to many relationship it is necessary to implement a third junction table between the two entities. We could, say, name it travel. This table uses two foreign keys, one from each entity, to form one compound key.
Now you have 3 tables. One table called 'Traveller', one called called 'City' and a third junction table called 'Travel'. Lets assume the primary key for traveller is travellerId and for city it's cityId. The junction table takes these two keys to form a primary key for the entity 'Travel'. When u query the database for which cities a traveller with travelId '031' has travelled to it would make use of this junction table and return the cityId's to you.
If this doesn't help or if you need more clarification I recommend searching these terms:
Many-to-many
Cardinality

Creating a one-to-one relationship between tables with an existing one-to-many relationship

So I have these two tables in my database:
Companies
--------------------
CompanyID (PK)
Name
Employees
--------------------
EmployeeID (PK)
CompanyID (FK)
Name
Basically, one company has many employees.
But I'd like to have each company have exactly one employee who is the Main Contact. My initial thought was to just add a MainContactID field to the Companies table that references the EmployeeID in Employees, but that would create a loop with the relationships.
What's the best way to do this?
There is nothing (in my opinion) wrong with your initial thought.
Although there is a loop as you put it, there isn't a problem here.
Having companies.MainContactEmployeeID ensures that there is only one such contact per company.
Then, adding a foreign key of Companies(CompanyID,MainContactEmployeeID) : Employees(CompanyID,EmployeeID) ensures that the employee actually works for that company. (Requires a matching unique index on the Employee table as well).
Such a foreign key is only possible because of the 'loop'. It's certainly not a problem.
We do something simliar with addresses and emails and phones. We have a field that marks the record as the main one. This field is then maintained through a trigger so that if the main contact point changes, you still have only one and if the main contact is deleted, the trigger uses the business rules to figure out which remaining record would get the flag, since we must have at least one main record if we have any records at all.
i personally prefer this model:
Organization
-------------
organization_id
name
other_columns
Person
-------------
person_id
name
other_columns
Person_Organization
--------------------
person_id
organization_id
begin_date
end_date
relationship_cd
this allows people to work for more than one organization at a time (certainly possible) and allows you to be very flexible on the relationship definitions - so 'how' was this person related to this org at this time... (important for contractors etc.)
If you don't want to have
circular paths in the FK relationships
Nulls in the FK columns
you can use this:
Add a UNIQUE constraint in Employee(CompanyID, EmployeeID) and make another table:
Company_MainContact
--------------------
CompanyID (PK) (FK1-->Employee)
EmployeeID (FK1-->Employee)
Creating a table with a combined primary key, like this:
Company_MainContact
--------------------
EmployeeID (PK) (FK-->Employee)
CompanyID (PK) (FK-->Company)