SQL Schema Design: Associated with many tables? - sql

Lets say I have a database with 4 types of things in it: Neighborhood, City, Houses, and Comment, like so
City:
name
ID
Neighborhood:
name
ID
CityID (foreign key to City:ID)
House:
name
ID
NeighborhoodID (foreign key to Neighborhood:ID)
CityID (foreign key to City:ID)
Comment:
ID
Text
???? (key to the subject of the comment)
I want users to be able to comment on a City, a Neighborhood or a House. How do I express this relationship in SQL?
One idea I had was to create 3 one to many relationship tables:
CommentToCity:
commentID
cityID
then when fetching the list of Cities, I could do a join on this table as well to get the related comments. I would then create a similar situation for House and Neighborhood.
Another idea would be to have globally unique identifiers in City, House and Neighborhood, and then have that global ID be the foreign key in the comment. Then when fetching the City it would do a join on comments looking for that global ID.
Are either of these a good way? Is there a better way?

Add a commentID to City, Neighborhood And House. (foreign key to comment:Id)
This way you just create an empty comment and add its Id if there is no comment on something.

Related

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

Unsure if my ER Diagram to relational model is correct

Ok, I'm brand new to SQL etc so apologies if this is totally wrong..
I have designed an ER Model which I feel is right and I am trying to convert it to relational model and want any advice as to where I am gone wrong on converting it or any tips. Racking my brain.
As I believe it..
1-1 relationships
entities are either combined or the primary key of one entity type is placed as a foreign key in the other relation.
1-m relationships
The primary key from the `one side' is placed as a foreign key in the many side.
m-n relationships
A new relation is created with the primary keys from each entity forming a composite key.
multivalue attributes
a new table is created, primary key used from 1st table and attribute used in the second table alognside primary key.
So here's my go at Relational model, PK in bold, FK in italics
USER:
USERID FNAME LNAME USERNAME PASSWORD USERTYPE EMAIL
CUSTOMER:
USERID, CUST_ID, BIO
ADMIN:
USERID ADMIN_ID
ARTIST
USERID, ARTIST_ID, BIO REC_ID
PRODUCER:
PROD_ID, Name, Email
RECORD LABEL:
RECORD_ID , NAME, DESCRIPTION
ALBUM:
ALBUMID NAME , COST, TITLE, NOOFSONGS
TRACK:
TRACK ID, NAME, COST, TITLE, DESCRIPTION
TRACK REVIEW: DEPENDENT on TRACK SO TRACK ID comes into this table =
REVIEW_ID(PK), TRK_ID(PK) NAME
TRACK PURCHASE TABLE (USER id comes into this table as foreign key)
TrackPuchaseID user_id, date
ALBUM PURCHASE TABLE
AlbumPuchaseID user_id, date, quantity
GENRE TABLE?:
Not sure??
BPM: is mutli value atribute so becoems seperate table so it.s
GenreID BPM
I know this all might be wrong. but any help would be great.. with explanation which should be FK or composite PK etc or what tables I am missing..
On album purchase you should have: user_id, date, album_id.
At track purchase I don't see why you care about the quantity and
you're missing the track_id.
review, track, album, user should all include a date. Might
be as well interesting to add an last_update_date to the artist
and customer.
review should include an user_id.
I guess there's other thing left. You will need an Invoice / Invoice_Purchase table to be able to say "customer xyz bought the items 1,2,3,4...", it should be like:
Table Invoice
invoice_id
user_id
date
status
Table Invoice_Purchase
invoice_id // Id of the invoice
purchase_type // the type of the purchase (for eg. 0 means track and 1 means album)
Maybe you should also add a status to your albuns and tracks, this way you can set if a item can be bought or not. And yes, you shouldn't delete them because you'll have the old invoices relaying on it...
Anyways, you should consider later using a software like Navicat do draw the relation part and deploy your DB.
From an initial look, here are some of my impressions, in no particular order.
1-1 relationships: not only is the PK of the entity defined as a FK in the related table, it is also the related table's PK. This preserves the unity of the relationship.
multivalue attributes: in other words, a 1-m relationship.
There is no reason to have separate ID values for Customer, Admin or Artist. In fact, call them all ID. I would say this is a m-1 relationship as a user could be both a customer and an artist. But the relationship between User table and the others individually are 1-1.
Isn't Track related to Album? So wouldn't AlbumID be a Track attribute?
Purchase tables should have CustID not UserID and be FK to Customer table. This enforces the need that a purchaser be defined as a customer.
Genre could be an attribute of track or album or both. An album could be generally "Country" but have a "Blues" track, a "Pop" track, etc.
Same for producer. There will be an album producer but could be one or more tracks produced by someone else.
Same for artist. There may be one artist for the entire album but what about "The Greatest Top 40 Hits of the 1980s"?
You may want an intersection table between Artist and Label. A label can sign up many artists and an artist could work for many labels (though generally not at the same time).
I have no idea what a BPM is.
That should keep you busy for a while.

Is this a good database design practice?

I got a Person table, each Person can visit several countries. The countries visited by each Person is stored in table CountryVisit
Person:
PersonId,
Name
CountryVisit:
CountryVisitId (primary key)
PersonId (foreign key to 'Person.PersonId')
CountryName
VisitDate
For the CountryVisit Table, my primary key is CountryVisitId which is an identity column. This design will result in that a Person can have only 1 CountryVisit but the CountryVisitId can be 40 for example. Is it a better practice to create another surrogate key column to act as an identity column while the CountryVisitId be a natural key that is unique for each PersonId ?
It is pretty good. I would suggest that you have a separate table for countries, with one row per country. Then the CountryVisits table would have:
CountryVisitId PrimaryKey,
PersonId ForeignKey,
CountryId ForeignKey,
VisitDate
This will ensure that the country name is always spelled correctly and consistently. If you want a list of countries to get started, check out this Wikipedia page. Also note that your definition of country may be different from the standard list of countries (there are actually several out there), so you should use your own auto-incremented primary key, rather than using the country code.
And, you should relax the requirement and remove the unique or primary key on PersonId, CountryId, unless you want to enforce only one visit per country.

Implementing one to many relationship

I'm new in programming. I'm designing a database that has two tables: Addresses and Customers. I don't know how to assign foreign keys. I don't know which way is better to use:
Method1:
Customer Table Columns:
CustomerID
FirstName
LastName
Address ID
Addresses Table Columns:
AddressId
Country
State
City
AddressLine
Method2
Customer Table:
CustomerId
FirstName
LastName
Addresses Table:
AddressId
CustomerId
Country
City
AddressLine
In other words I don't know where to place the foreign key.
If you are trying to implement one to many, so the recommended way is to put the primary key for the table besides the one into the table of the many as a foreign key..
For example: if one costumer have many addresses and address have one costumer. so you will have to put the costumerId as a foreign key in the table of the address.
if one address can have many costumers and one costumer have one address. so you will have to put the AddressNumber as a foreign key in the table of the costumers.
Good Luck
If each customer can have many addresses, then you want to use method 2 because then there can be multiple records in Addresses for each customer in Customer.
However, it seems to me like you might need a many-to-many relationship. What happens if two customers share the same address?
You can accomplish this by including a third table, e.g. CustomerAddresses that logically sits in between Customer and Addresses. This third table will hold the foreign keys from both of the other tables -- CustomerID and AddressID.
In your first method, one customer could only be associated to one address, as it has only one id referring to an address. But nothing prevents several customers from having the same address id. So this represent a many-customer-to-one-address relation. That's not what you want.
In your second method, the relation is reversed. Each address is associated to a customer, several addresses can be associated to the same customer, the is a one-customer-to-many-addresses relation.
In sql, to retrieve the addresses associated with a customer, you would do:
select * from address where customer_id = '<some customer_id>'
I will point out that you may actually have a many to many relationship. One address can have more than one customer and one customer can have more than one address. In this case you use a Join table to model the relationship that contains the addressid and the customerid and nothing else. This would have a join PK of both those fields to ensure uniqueness.