I'm creating a small news website and someone suggested that I look at normalisation, which I did and although I understand it I don't quite know if it's relevant to ALL tables in a database. For instance, I have this "Articles" table consisting of:
ID - 10001
Featured - 0 or 1
Category - Category Name
Title - Title For The Article
Article - This is the article.....
Photo Description - Photo to go with blog 10001
Photo Name - John Smith
Photo Link - www.johnsmith.com
Author - myname#gmail.com
Keywords - keyword, keyword, keyword, ...
Added - 2014-07-27 10:41
Views - 600
Is there anything wrong with leaving this table as it is or does it need to be converted to 3rd normal form?
EDIT:
What if I had:
**Authors**
ID
email
name
avatar
bio
website_link
facebook_link
twitter_link
**Articles**
ID - 10001
Featured - 0 or 1
Title - Title For The Article
Article - This is the article.....
Photo - 10001.jpg
Photo Description - Acts as alt tag
Photo Name - Crediting photographer
Photo Link - Link to credited photographer
Author - Author ID
Added - 2014-07-27 10:41
Views - 600
**categories**
ID
category
**article_categories**
ID
article_id
category_id
I'm still finding it hard to grasp the reasons why having so many tables is such a great thing though as now there are lots of joins that need to be made. Why isn't it easier to use php to say
select * from articles where category == $category
or
select * from articles where featured == 0
or
select * from articles where author == $author_id, etc, etc
Make seperate table for news,category,photo,authors and keywords
News
ID - 10001
Featured - 0 or 1
category_id - //belongs to category table
Title - Title For The Article
Article - This is the article.....
Added - 2014-07-27 10:41
Views - 600
categories
ID
name
Photos
ID
Photo Description - Photo to go with blog 10001
Photo Name - John Smith
Photo Link - www.johnsmith.com
Authors
ID
Author - myname#gmail.com
keywords
ID - 10001
Keywords - keyword
One news may have multiple photos so make one bridge table news_photos
news_photos
id
news_id
photo_id
Similarly One news may have multiple authors so make one bridge table news_authors
news_authors
id
news_id
author_id
Also One news may have multiple keywords so make one bridge table news_keywords
news_keywords
id
news_id
keyword_id
You duplicate much strings that describe category name. Much easier store integer value, instead category name each time.
I reccomend you at least to move the Category and the Keywords in separate tables.
This will help you to write more effective SQL queries when you will have to search Articles by keywords or category.
On the other hand, you will have to write more code to do this, referring to data insert form, etc., but it will be better and more clear and absolutely better.
You should then:
Create a Categories table (Id, Description)
Create a Keywords table (Article_Id, Keyword)
Substitute your Articles.Category field with Articles.Category_Id and remove your Articles.Keywords field.
How you choose to normalize largely depends on your business case, don't just normalise for the sake of it. That's why your design approach is crucial, starting off with an ERD (Top-Down approach) helps me in deciding how best to normalize.
Related
I am pretty new to database schema design. So this may sounds trivial to experts
I am designing a app that store photo for each trip I created.
So, I have one table storing trips and one table storing some photos belonging to each trips.
So, things seems easy for designing this table . And below are my drafted schema
Trips
ID
title
created_at
Photos
ID
title
created_at
image_location
trip_id
Here is the problem:
If I would like to show the order of photos, I can make use of the attribute of created_at in Photos.
But what if one day I would like to rearrange the order of images or I inadvertently assign the photos with wrong order at the first time I add it into the trip.
What I come up with is that I try to make an column called order_no in Photos, so when there is new photos added, its order_no would be increased by one and assigned to it.
Photos
ID
title
created_at
trip_id
order_no
However, the problem is that I will have to update every order_no to keep the sequence order consistent when there is a new rearrangement
For example , I would like to rearrange the position of photo4 , the original order is like below
1 photo1
2 photo2
3 photo3
4 [photo4]
1 [photo4]
2 photo1 (order_no need to be changed from 1 to 2)
3 photo2 (order_no need to be changed from 2 to 3)
4 photo3 (order_no need to be changed from 3 to 4)
Is there a consistent way to implement this ?
Thanks
I have the database design below:
table design
basically, I need to be able to input products that have the following columns:
id, area, category, name
The problem is that if I create the database to the spec in the image above, then wouldn't that still cause repeats in the table catalogue? which would be against the normal forms.
Also it means that the data in catalogue would just be numbers aka references to the other tables. Is there a solution to this issue? as I imagine any catalog site that has a db back-end would have the same issue.
Here is an example that is the same issue just different sinorio if it helps:
I have a product catalog that sells laptops and TVs, do I make a table that has the type of device? because that would look like this:
id - name - type - etc
1 - acerP - laptop - null
1 - acerP - laptop - null
1 - acerP - TV - null
Notice how 'laptop' could get repeated 100s of times, normally you would create a new table that has just:
u_id - type
101 - laptop
102 - TV
Then simply join then in the query, but then you would have in the device table:
id - name - type - etc
1 - acerP - 101 - null
1 - acerP - 101 - null
1 - acerP - 102 - null
but now you are repeating the number references.
Am I missing something here, or is this normal?
This is norma, only foreign keys would be repeated in your proposed structure, which is allowed by the 1NF:
First normal form enforces these criteria:
- Eliminate repeating groups in individual tables.
...
Groups means a combination of columns. The same category may appear more than once in catalogue, but not, for example the couple (category, area).
I am putting together a database which will hold information on various media items of different media types. Each media item could then be added to a media collection which could then be used to create media sliders, galleries etc.
Here is an example db
media_types
-----------
id code title
1 images Images
2 videos Videos
3 files Files
gallery_items
-------------
id gallery_id mediaTypeId mediaId
1 1 1 2
2 1 3 1
3 1 2 3
images
------
id title filename
1 X-Wing xwing.png
2 Tie Fighter tie.png
3 A-Wing awing.jpg
videos
------
id title filename
1 Hoth iceplanet.wmv
2 Bespin bespin.ogg
3 Tatooine desert.mpeg
files
-----
id title filename
1 Death Star Plans bothanx.pdf
2 Millenium Falcon Schematics yt1300.pdf
3 Rebel Alliance manifesto.doc
I would like to be able to select all items in a particular gallery with one MySql statement but at present, I can only work out how to perform it in two steps:
1) Select all items from the gallery_items table with a particular gallery id
2) Select the item details from the relevant media type table by analysing the mediaTypeId
In the example I give, the media type tables are very simple, sharing the same columns but in reality they will have different amounts of columns and different column names. A basic join statement on mediaId won't work as each media type table could share the same id.
I had thought about using a unique mediaId across all media types but this would enforce an absolute relationship between the gallery_items table and the media types tables which I would like to avoid (not all items in the media types tables will end up in a media collection). Perhaps the solution would be to create another table, media_items, which created a unique media id for each each which would then be used in each media type table? I am however weary of unnecessary table proliferation.
Any suggestions on how to best approach this design would be most appreciated.
IIWM: I would have one table of 'media types' like you have it. Then another table of media with a unique ID, media type, filename, etc. Last have a table with gallery info - unique id, media id and any other gallery info.
To make it more useful you could have a table of 'changes' that track datetime of assignments to/from a gallery for each piece of media, date it was received, sold, etc. This would track the 'lifespan' of each piece in your collection.
I am developing an evaluation system for different programs that needs a lot of flexibility. Each program will have different things to track, so I need to store what data points they want to track, and the corresponding data for the person being evaluated on the particular data point. I am guessing several tables are appropriate. Here is a general outline:
Table: accounts
- unique ID assigned to each account. We'll call this 'aid'
Table: users
- each user with unique ID.
Table: evaluation
- each program will enter in the metrics they want to track into this table (i.e attendance)
- column 'aid' will correspond to 'aid' in account table
Table: evaluation_data
- data (i.e attendance) entered into this database
- column 'aid' will correspond to 'aid' in account table
- column 'uid' will correspond to 'uid' in user table
The input form for evaluation_data will be generated from what's in the evaluation table.
This is the only logical way I can think of doing this. Some of these tables will be growing quite large over time. Is this the most optimal way of doing this?
I'm a little confused about how accounts, users and programs all relate to each other and whether or not account and program are the same thing and that you used the terms interchangeably. I'm going to use different terms which are just easier for me to understand.
Say you have a website that allows freelancers to keep track of different projects and they can create their own data to track. (Hope you see the similarity)
Tables...
freelancers
id title etc
projects
id freelancer_id title description etc
data_options
id freelancer_id title
You can even add other columns like data_type and give options like URL, email, text, date, etc which can be used for validation or to help format the input form.
example data:
1 5 Status
2 5 Budget
3 5 Customer
4 99 Job Type
5 99 Deadline
6 102 Price
7 102 Status
8 102 Due By
This display 3 different freelancers tracking data, freelancers with the id's 5, 99, and 102. Deadline and Due By are essentially the same but freelancers can call these whatever they want.
data_values
id project_id option_id option_value
a column freelancer_id as you would be able to to a join and get the freelancer_id from either the project_id or the option_id
example data:
1000 1 2 $250
1001 1 1 Completed
1002 1 3 Martha Hayes
This is only showing information freelancer with the id 5 has input because option_id's 1-3 belong to that user.
Assume a list of names in a table called authors. Each author has written some books during his lifetime. Important: You don't know the explicit dates when the books were published. (If I would now the exact dates, I could just order by that in each query and I would be good.) You only know the order of the books' publication. The books are stored in a table books. We have a Many-To-Many-Relation between authors and books.
The question: How would you store the order of a publication history of each of the authors?
Example:
Luc - title_1
Luc - title_2
Luc - title_10
Luc - title_234
Peter - title_1
Peter - title_5
Peter - title_10
Peter - title_987
John - title_2
John - title_5
John - title_9
...
At the moment I am storing for each author a string of comma separated Values (primary keys of the books) to remember the order of the publications of a certain author in a column called books_order.
id name publication_order
...
4 john (2, 5, 9)
...
But that is certainly the wrong way to go. How to normalize that?
I would add an extra column called sortorder or somethin similar. The first book gets a 1, the second a 2 ... etc. With that, you can use ORDER BY author, sortorder to get a list of books sorted by author and order of publication.