How to avoid arrays in relational database? - sql

My database describes companies websites. A company website has several attribute: URL, load time, etc. Each website is targeting one or several countries. I have problems expressing the relation between the website and the countries.
My setup number 1 looks like this:
A Company table
A Country table
A Website table, with fields WebsiteId, CompanyId (refers to Company.id), Countries (array referring to Country.id) and several attributes like URL, LoadTime, etc.
My setup number 2 looks like this:
A Company table
A Country table
A Website table, with fields WebsiteId, CompanyId (refers to Company.id) and several attributes like URL, LoadTime, etc.
A WebsiteCountries table, with fields WebsiteId, CountryId
I have problem with both approaches:
Setup number 1 uses an array of Country.id, which makes it hard to maintain
In setup number 1, CompanyId has a unique constraint in the Website table, but allows duplicate in setup number 2. More generally, CompanyId + Countries could act as a candidate key in setup 1. This disturbs me a bit : am I wrong and is it the best approach?

#Jodrell already gave you the correct answer - "setup number 2" with compound PK is the best solution. I'll just explain it in details.
There are companies, countries and websites. For each of them we create a separate table.
Now it's time for references:
If a company may have only one website, then it's one-to-one relationship. If it may have many websites, then it's one-to-many relationship. In both cases you have a foreign key CompanyId in Website table - it'll only differ in UNIQUE constraint.
You write "Each website is targeting one or several countries." Additionally, for every country there may be one or more websites (for different companies). It means that it's a classical many-to-many relationship. In such case you must add a junction table - WebsiteCountries. Here you'll have a compound primary key that constists of two columns: (WebsiteId, CountryId). This'll prevent from duplicates.
Hope this helps.

Related

SQL Join to either table, Best way or alternative design

I am designing a database for a system and I came up with the following three tables
My problem is that an Address can belong to either a Person or a Company (or other things in the future) So how do I model this?
I discarded putting the address information in both tables (Person
and Company) because of it would be repeated
I thought of adding two columns (PersonId and CompanyId) to the
Address table and keep one of them null, but then I will need to add
one column for every future relation like this that appears (for
example an asset can have an address where its located at)
The last option that occur to me was to create two columns, one
called Type and other Id, so a pair of values would represent a
single record in the target table, for example: Type=Person,Id=5 and
Type=Company,Id=9 this way I can Join the right table using the type
and it will only be two columns no matter how many tables relate to
this table. But I cannot have constraints which reduce data integrity
I don't know if I am designing this properly. I think this should be a common issue (I've faced it at least three times during this small design in objects like Contact information, etc...) But I could not find many information or examples that would resemble mine.
Thanks for any guidance that you can give me
There are several basic approaches you could take, depending on how much you want to future proof your system.
In general, Has-One relationships are modeled by a foreign key on the owning entity, pointing to the primary key on the owned entity. So you would have an AddressId on both Company and Person,which would be a foreign key to Address.Id. The complexity in your case is how to handle the fact that a person can have multiple addresses. If you are 100% sure that there will only ever be a home and work address, you could put two foreign key columns on Person, but this becomes a big problem if there's a third, fourth, fifth etc. address. The other option is to create a join table, PersonAddress, with three columns a PersonId an AddressId and a AddressType, to indicate whether its a home work or whatever address.

how database relationship work in databases [duplicate]

This question already has answers here:
Meaning of "n:m" and "1:n" in database design
(9 answers)
Closed 3 years ago.
I have started a new job recently as .Net Developer, in that for the projects that I am working on requires strong understanding of relationships like
1-N, 1-1 and N-N. I have completely understood 1-1 relationship with real life example like In a Tablets and Billing table if Billing table has TabletId as a foreign key then there is 1-1 relationship between them, but talking about 1-N and N-N relationship regarding same tables how the real life example can be put forward. I have not completely understood.
Tablet
TabletId
Name
description
Maker
ExpiryDate
Billing
BillingId
TabletId F.K
TDate
so from above table structure it is clear that one bill can have one tablet only. but if i want one bill can have multiple tablets then how will i achieve that.
Please give me example of Tablets and Billing table for 1-N and N-N relationships
When talking about relationships in a database, one could be more precise by stating the minimum and maximum links. The relations we usually see in a database are:
1:1 implemented as {1}:{0,1} Example: a user has or doesn't have one address. So, each user has 0 to 1 addresses; an address belongs to one user.
1:n implemented as {1}:{1,n} Example: a user has one or more or no phone numbers. So, each user has 0 to n phone numbers; a phone number belongs to one user.
m:n implemented as {0,m}:{0,n} Example: a product in one or more or no shops; a shop sells one or more or no products.
And here is how we omplement these relations:
The address table has a user ID and it's the table's primary key.
The phone table has a user ID.
There is a bridge table linking product and shop consisting of these two columns: product ID and shop ID.
Of the three relations the first (1:1) is rare. Usually we would rather store the values in a single table. But in the address example we could use it to easily guarantee that a user either has a full address with both street and city and country given or none at all.
The 1:n and m:n relations are both frequent in databases.

How to design a media table with references to multiple (at least 4) tables?

I am designing a database for my cookbooks. I have created multiple tables in my design: books, authors, recipes, ingredients and for all these items I want to link media (images or video) to items in all these tables.
I was thinking of a design like:
media_id,
rid (primary key of foreign table),
rtype (1=book, 2=author, 3=recipe, 4=ingredient),
media_type(1=image,2=video),
media_url
But how will I ensure relational integrity?
Thanks
Your proposed design seems to imply that each entity (book, author, etc.) can have multiple media files, so to maintain relational integrity, I'd have separate junction tables for each relationship.
If there's only 1 media-item for each table, the media_id should be in the tables in stead of the other way around.
If several media-items are possible you shoud link them within an extra table. There should be an extra table per item (bookid_mediaid for example).
If you think it should be linkable within one table, you are actually stating that those items have at least something in common. Otherwise the rid would have different meaning throughout the records, depending on type, and that's not possible in relational theory.
Concluding :
Your design is not good. Either you should have a relationship per entity or find what's common for all entities and use that to link to your mediatypes.
Matthijs,
For a relational design, you have to look at how these objects are related to each other and then decide on the data model. Here is an initial draft and the conditions that I am assuming. You might have different rules for your case.. post them and someone should be able to post an accurate model.
Each book can be written by many authors and each author can write different books. ( M:N)
RECIPES <--> BOOKS (M:N)
RECIPES <--> INGREDIENTS (M:N)
These would be the initial set of tables.
BOOKS, AUTHORS, BOOKS_AUTHORS_ASC, RECIPES, BOOKS_RECIPES_ASC,
INGREDIENTS, RECIPES_INGREDIENTS_ASC.
If the media is related to one and only one book, you'll have a different table , say, media with the following columns. BOOK_ID is the parent column to which this media is associated.
MEDIA
-------------------------------------
MEDIA_ID NUMBER -- Primary-key
BOOK_ID NUMBER -- Foreign Key..
MEDIA_TYPE varchar2(20) -- 'IMAGE','VIDEO' etc..
other_column1 varchar2(50),
other_column2 varchar2(50)
-- so on..
And if a given image/video can be associated to multiple books and each book can have different images, then you'll have a different entity for the association.. something like..
Media
--------
Media_id number -- primary key
media_type varchar2(10),
media_name varchar2(100),
--- other columns.
MEDIA_BOOK_ASC
--------------
MEDIA_BOOK_ASC_ID NUMBER,
MEDIA_ID NUMBER, --foreign key to media table.
BOOK_ID NUMBER, --foreign key to book table
--other columns related to associations...

Relational Database Design (MySQL)

I am starting a new Project for a website based on "Talents" - for example:
Models
Actors
Singers
Dancers
Musicians
The way I propose to do this is that each of these talents will have its own table and include a user_id field to map the record to a specific user.
Any user who signs up on the website can create a profile for one or more of these talents. A talent can have sub-talents, for example an actor can be a tv actor or a theatre actor or a voiceover actor.
So for example I have User A - he is a Model (Catwalk Model) and an Actor (TV actor, Theatre actor, Voiceover actor).
My questions are:
Do I need to create separate tables to store sub-talents of this user?
How should I perform the lookups of the top-level talents for this user? I.e. in the user table should there be fields for the ID of each talent? Or should I perform a lookup in each top-level talent table to see if that user_id exists in there?
Anything else I should be aware of?
before answering your questions... i think that user_id should not be in the Talents table... the main idea here is that "for 1 talent you have many users, and for one user you have multiple talent".. so the relation should be NxN, you'll need an intermediary table
see: many to many
now
Do I need to create seperate tables to store sub-talents of this
user?
if you want to do something dynamic (add or remove subtalents) you can use a recursive relationship. That is a table that is related to itself
TABLE TALENT
-------------
id PK
label
parent_id PK FK (a foreign key to table Talent)
see : recursive associations
How should I perform the lookups of the top-level talents for this
user? I.e. in the user table should
there be fields for the ID of each
talent? Or should I perform a lookup
in each top-level talent table to see
if that user_id exists in there?
if you're using the model before, it could be a nightmare to make queries, because your table Talents is now a TREE that can contain multiple levels.. you might want to restrict yourself to a certain number of levels that you want in your Talent's table i guess two is enough.. that way your queries will be easier
Anything else I should be aware of?
when using recursive relations... the foreign key should alow nulls because the top levels talents wont have a parent_id...
Good luck! :)
EDIT: ok.. i've created the model.. to explain it better
Edit Second model (in the shape of a Christmas tree =D ) Note that the relation between Model & Talent and Actor & Talent is a 1x1 relation, there are different ways to do that (the same link on the comments)
to find if user has talents.. join the three tables on the query =)
hope this helps
You should have one table that has everything about the user (name, dob, any other information about the user). You should have one table that has everything about talents (id, talentName, TopLevelTalentID (to store the "sub" talents put a reference to the "Parent" talent)). You should have a third table for the many to many relationship between users and talents: UserTalents which stores the UserID and the TalentID.
Here's an article that explains how to get to 3rd NF:
http://www.deeptraining.com/litwin/dbdesign/FundamentalsOfRelationalDatabaseDesign.aspx
This is a good question to show some of the differences and similarities between object oriented thinking and relational modelling.
First of all there are no strict rules regarding creating the tables, it depends on the problem space you are trying to model (however, having a field for each of the tables is not necessary at all and constitutes a design fault - mainly because it is inflexible and hard to query).
For example perfectly acceptable design in this case is to have tables
Names (Name, Email, Bio)
Talents (TalentType references TalentTypes, Email references Names)
TalentTypes (TalentType, Description, Parent references TalentTypes)
The above design would allow you to have hierarchical TalentTypes and also to keep track which names have which talents, you would have a single table from which you could get all names (to avoid registering duplicates), you have a single table from which you could get a list of talents and you can add new talent types and/or subtypes easily.
If you really need to store some special fileds on each of the talent types you can still add these as tables that reference general talents table.
As an illustration
Models (Email references Talents, ModelingSalary) -- with a check constraint that talents contain a record with modelling talent type
Do notice that this is only an illustration, it might be sensible to have Salary in the Talents table and not to have tables for specific talents.
If you do end up with tables for specific talents in a sense you can look at Talents table as sort of a class from which a particular talent or sub-talent inherits properties.
ok sorry for the incorrect answer.. this is a different approach.
The way i see it, a user can have multiple occupations (Actor, Model, Musician, etc.) Usually what i do is think in objects first then translate it into tables. In P.O.O. you'd have a class User and subclasses Actor, Model, etc. each one of them could also have subclasses like TvActor, VoiceOverActor... in a DB you'd have a table for each talent and subtalent, all of them share the same primary key (the id of the user) so if the user 4 is and Actor and a Model, you would have one registry on the Actor's Table and another on the Model Table, both with id=4
As you can see, storing is easy.. the complicated part is to retrieve the info. That's because databases dont have the notion of inheritance (i think mysql has but i haven't tried it).. so if you want to now the subclases of the user 4, i see three options:
multiple SELECTs for each talent and subtalent table that you have, asking if their id is 4.
SELECT * FROM Actor WHERE id=4;SELECT * FROM TvActor WHERE id=4;
Make a big query joining all talent and subtalent table on a left join
SELECT * from User LEFT JOIN Actor ON User.id=Actor.id LEFT JOIN TvActor ON User.id=TvActor.id LEFT JOIN... WHERE User.id=4;
create a Talents table in a NxN relation with User to store a reference of each talent and subtalents that the User has, so you wont have to ask all of the tables. You'd have to make a query on the Talents table to find out what tables you'll need to ask on a second query.
Each one of these three options have their pros and cons.. maybe there's another one =)
Good Luck
PS: ahh i found another option here or maybe it's just the second option improved

What to do if 2 (or more) relationship tables would have the same name?

So I know the convention for naming M-M relationship tables in SQL is to have something like so:
For tables User and Data the relationship table would be called
UserData
User_Data
or something similar (from here)
What happens then if you need to have multiple relationships between User and Data, representing each in its own table? I have a site I'm working on where I have two primary items and multiple independent M-M relationships between them. I know I could just use a single relationship table and have a field which determines the relationship type, but I'm not sure whether this is a good solution. Assuming I don't go that route, what naming convention should I follow to work around my original problem?
To make it more clear, say my site is an auction site (it isn't but the principle is similar). I have registered users and I have items, a user does not have to be registered to post an item but they do need to be to do anything else. I have table User which has info on registered users and Items which has info on posted items. Now a user can bid on an item, but they can also report a item (spam, etc.), both of these are M-M relationships. All that happens when either event occurs is that an email is generated, in my scenario I have no reason to keep track of the actual "report" or "bid" other than to know who bid/reported on what.
I think you should name tables after their function. Lets say we have Cars and People tables. Car has owners and car has assigned drivers. Driver can have more than one car. One of the tables you could call CarsDrivers, second CarsOwners.
EDIT
In your situation I think you should have two tables: AuctionsBids and AuctionsReports. I believe that report requires additional dictinary (spam, illegal item,...) and bid requires other parameters like price, bid date. So having two tables is justified. You will propably be more often accessing bids than reports. Sending email will be slightly more complicated then when this data is stored in one table, but it is not really a big problem.
I don't really see this as a true M-M mapping table. Those usually are JUST a mapping. From your example most of these will have additional information as well. For example, a table of bids, which would have a User and an Item, will probably have info on what the bid was, when it was placed, etc. I would call this table... wait for it... Bids.
For reporting items you might want what was offensive about it, when it was placed, etc. Call this table OffenseReports or something.
You can name tables whatever you want. I would just name them something that makes sense. I think the convention of naming them Table1Table2 is just because sometimes the relationships don't make alot of sense to an outside observer.
There's no official or unofficial convention on relations or tables names. You can name them as you want, the way you like.
If you have multiple user_data relationships with the same keys that makes absolutely no sense. If you have different keys, name the relation in a descriptive way like: stores_products_manufacturers or stores_products_paymentMethods
I think you're only confused because the join tables are currently simple. Once you add more information, I think it will be obvious that you should append a functional suffix. For example:
Table User
UserID
EmailAddress
Table Item
ItemID
ItemDescription
Table UserItem_SpamReport
UserID
ItemID
ReportDate
Table UserItem_Post
UserID -- can be (NULL, -1, '', ...)
ItemID
PostDate
Table UserItem_Bid
UserId
ItemId
BidDate
BidAmount
Then the relation will have a Role. For instance a stock has 2 companies associated: an issuer and a buyer. The relationship is defined by the role the parent and child play to each other.
You could either put each role in a separate table that you name with the role (IE Stock_Issuer, Stock_Buyer etc, both have a relationship one - many to company - stock)
The stock example is pretty fixed, so two tables would be fine. When there are multiple types of relations possible and you can't foresee them now, normalizing it into a relationtype column would seem the better option.
This also depends on the quality of the developers having to work with your model. The column approach is a bit more abstract... but if they don't get it maybe they'd better stay away from databases altogether..
Both will work fine I guess.
Good luck, GJ
GJ