How to model many-to-many relationships in SQL? - 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

Related

Is it correct to have a table in SQL with just foreign key columns?

Is it correct to have a table in SQL with just foreign key columns? All columns are foreign keys, except the primary key ID.
Here is the scenario in my mind. I wanted to be sure first and then implemented it.
I have three tables => Personnel, Position, Place. Personnel table has general information of employees, Position table has different job positions and tasks in a company, Place table has info about different places in the city. So, an Agent is one of the personnel with one of the job tasks who should go to do the task in one of the places. Agents could change every week, select between personnel and give them almost randomly tasks and places.
I'll give you an example where it is perfectly correct and desired:
when you have many to many relationship, say Table1 and Table2 the best practice states that you should have table, eg. Table1Table2 with just two columns: Table1Id and Table2Id, both foreign keys to respective tables and together they make primary key.
Having said that, it is perfectly correct, as long as it satisfies your design.
To say anything more, you should share your database schema.
you should add a foreign key on the child table referencing the parent table so it is correct that all fields be foreign key but you have to have primary key on that table.

Should a table containing couples of rows from another table with similar attribute contain that data?

lets say we have a table of people, and the country theyre from.
and we have a table of couples, each row has to people, and every couple will always belong to the same country.
do we want to save the country on the couples table?
will this count as normalized? redundant?
If you want to enforce the rule that couples must belong to the same country, you can include country in the couples table. See my answer to How to preserve data integrity in circular reference database structure? for a similar situation and an example of how to implement this.
The country column in the couples table would be logically redundant and violate 2NF (assuming the table has the identifiers of the two persons as a primary or unique key) but the method of overlapping foreign key constraints eliminate the risk of data anomalies.

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

SQL Table Design: Multiple foreign key columns or general "fkName" and "fkValue" columns

Given a table (Contacts) which could apply to distinct items in a database (Employers, Churches, Hospitals, Government Groups, etc.) which are stored in different tables, when leveraging this single contacts table in the end I've found there exist two choices for relating a contact back to one particular "item"
One column for each "item" type with a Foreign Key association, this results in a table looking like:
contactID empID churchID hospID govID conFN conLN ...
One column indicating the type of "item" (fkName) and one column for the value corresponding to the item of that type (fkValue). This results in a table looking like:
contactID fkName fkValue conFN conLN ...
The first means that out of the X possible foreign keys, X-1 will be NULL, but I get the advantages of hard-associated foreign keys.
The second means that I can set fkName and fkValue as NOT NULL but I don't get the advantages of DB-supported foreign keys.
Ultimately, is there a "right" answer? Are there other advantages / disadvantages that I haven't thought about (performance, security, growth/expansion)?
The second approach is an anti-pattern.
You need to set up many-to-many relationship tables between each entity (Hospitals, Churches, Employers, Government Groups, etc.) and Contacts.
If you want to make it easier to query for all of the entities a contact is related to, consider creating a view on top of the many-to-many relationship tables.
I think the second option is better as it will allow you to maintain referential integrity of your database using the in-built SQL features (foreign keys), rather than relying on your code to maintain it.
This is the solution that you should be going towards:
type
----------------
typeId name
1 hospital
2 church
contact
-----------------------------------------
contactId firstName LastName typeId (fk)
1 bob is 1
2 your uncle 2
If Bob can be a contact for more than one type, than you will need a junction table.

How to design a circular reference to a single database table with an added relationship?

I'm not sure how best to phrase the question, but essentially I have a table of contacts, and instead of doing the typical -- a contact has a reference to a table with spouse information, and a table with children, I want each of those people to be a contact, but then define a relationship between those contacts (brother, sister, child, spouse, etc.). So the contacts would exist in a single table, but I'm having trouble determining how best to define the relationship based upon their contact id and the relationship type. Any advice would be appreciated.
CONTACTS table
contact_id, pk
CONTACT_RELATIONSHIP_TYPE_CODE table
contact_relationship_type_code, pk
description
CONTACTS_RELATIONS table
parent_contact_id, pk, foreign key to CONTACTS table
child_contact_id, pk, foreign key to CONTACTS table
contact_relationship_type_code, foreign key to CONTACT_RELATIONSHIP_TYPE_CODE table
If you see the need to support multiple relationship types to a pair of people, add the CONTACTS_RELATIONS.contact_relationship_type_code column to the composite primary key
This is called a self join, it is pretty common and fairly easy to provide the functionallity you mention above. Take a look at this article.
Just implement an intersect table with four columns - key, contactid #1, contact id#2, and relationship.
Why do it this way? Because a contact can have several relationships.