views:

114

answers:

4

In a classifieds website, you have several categories (cars, mc, houses etc). For every category chosen, a hidden div becomes visible and shows additional options the user may specify if he/she wishes.

I am creating a db now, and I have read some articles about normalization and making it optimized etc...

Here is my layup today

CATEGORY TABLE:
- cars
- mc
- houses

CLASSIFIED TABLE:
- headline
- description
- hide_telephone_nr
- changeable
- action
- price
- modify_date

POSTER TABLE:
- name
- passw
- tel
- email

AREA TABLE:
- area
- community

CARS TABLE:
- year
- fuel
- gearbox
- colour

MC TABLE:
- year
- type

HOUSE TABLE:
- Villa
- Apartment
- Size
- rooms
etc

I have so far one table for each category, so that is around 30 tables. Isn't that too many?

I haven't created PK or FK for any of these so far, haven't got that far yet...

Could you tell me if this setup is good, or should I have it made differently?

ALSO, how would you setup the FK and the PK here?

Thanks

+1  A: 

From my understanding, I would make a table for all the categories and store the categories' name and ID there. Next, I would create a separate table to store the additional options for each category.

MySQL Table 1  
----------------   
Category_ID int PRIMARY KEY  
Category_name varchar  

MySQL Table 2  
---------------- 
Category_ID int   
Entry_Number int PRIMARY KEY (this will keep track of which entry everything belongs to)
Additional_Option varchar  
Additional_Option_Answer varchar (this is the one that stores what your user clicks/inputs)

For example, using:

POSTER TABLE:
- name
- passw
- tel
- email

You would store the category_id this data is for in Category_ID and store name passw tel email into Additional_Option in it's own row and the user's input for those criteria would be stored in Additional_Option_Answer.

Category_ID for Posters will be 1 and for Area will be 2.

It would look like this if the first user added something:

---------------------------------------------------------------------------------------------
Category_ID   |    Entry_Number    |    Additional_Options   |   Additional_Options_Answers
---------------------------------------------------------------------------------------------
       1      |   1                |    name                 |   doug
       1      |   1                |    passw                |   1234

It would look like this if the second user added something:

---------------------------------------------------------------------------------------------
Category_ID   |    Entry_Number    |    Additional_Options   |   Additional_Options_Answers
---------------------------------------------------------------------------------------------
       1      |   2                |    name                 |   Hamlet
       1      |   2                |    passw                |   iliketurtles

Further more, let's apply another category:

AREA TABLE:
- area
- community

---------------------------------------------------------------------------------------------
    Category_ID   |    Entry_Number    |    Additional_Options   |   Additional_Options_Answers
    ---------------------------------------------------------------------------------------------
           2      |   3                |    area                 |   San Francisco
           2      |   3                |    community            |   community_name
Doug
please clarify, that's what I have done as you can see above... explain some more
pesar
I hope that clarifies it better :)
Doug
So users only insert data into the last table, the values table right? I get it! ie: CARS -> YEAR -> INSERTED VALUE (ex 2010) ?
pesar
The last table would be the only table with a custom input by the users; Yes.
Doug
ok, thanks Doug... only left to try it out now :)
pesar
Let me know how it goes :)
Doug
Wow, my first accepted answer! A milestone for my improvement!
Doug
A: 

You can recognise a problem with the category tables by the use of data in the table names. The problem with having tables for each category isn't mainly that you get many tables, but that you have to change the database design if you add another category. Also, querying the database is difficult when you need to select a table based on data.

You should have as single table for the posting properties instead of one for each category. As the properties for each category differs, you would also need a table that describes which properties are use for each category.

Tables that describe the main objects (category, classified, poster, area, property) would get a primary key. The other tables only need foreign keys, as they are relations between objects.

Category (CategoryId, CategoryName)

Classified (ClassifiedId, PosterId, AreaId, ...)

Poster (PosterId, ...)

Area (AreaId, AreaName, ...)

Property (PropertyId, PropertyName)

CategoryProperty (CategoryId, PropertyId)

ClassifiedProperty (ClassifiedId, PropertyId, Value)
Guffa
Ok, I think I understand... Could you explain your second paragraph a little more, how can I "describe which property are used for each category"... some example would be great Guffa!
pesar
CategoryProperty table u'll get to knw abt properties of each category.
neverSayNo
@pesar: The CategoryProperty table contains the properties for a category. For the "MC" category for example there would be two rows, one for the "Year" property and one for the "Type" property. A classified in the "MC" category would then have two rows in the ClassifiedProperty table, containing the values for the two properties.
Guffa
+1  A: 

First of all you need to create primary key for each table. Normally the best way to do this is to use sequential id field that is named either id or tablenameId. This is really important. Primary keys tied to the actual data will cause problems when the data changes.

category (id PK, name)
category_options (id PK, category_id FK->category.id, option_name)

So that category table would have values like

(1, car)
(2, MC)

and options would have values like

(1, 1, year)
(2, 1, fuel)
(3, 2, type)

Then you need a table where the values are actually stored and linked to the item. This just requires that you join all 3 category tables when you do a query for one item.

category_values (id PK, category_options_id FK-> category_options.id, value, classified_id FK->classified.id)

Classified table needs fk to poster and id field.

classified (id PK, poster_id FK->poster.id, headline, description, hide_telephone_nr, changeable, action, price, modify_date)

Poster table is quite good as it is just add id field for primary key. I just think that it is normally called users.

By category_options_id FK-> category_options.id I mean that category_options_id should have foreign key reference to category_options.id.

You could do even more normalizations like for classified.action and classified.changeable but it also adds complexity.

I hope this helps.

I must also stress that this is not the only possible solution and depending on how you actually want to use the data it might not be the best option but it works and is atleast decent :)

Calmar
Thanks for the answer. May I ask, why would you link (FK) classified table to the option_values table? I am still learning the logics here...
pesar
What is `FK->`? Edit: Foreign Key.
Doug
So classified table contains actual items on sale and category tables contain the possible categories the item has. As the values table has the actual values it is best to link that to the classified table as there is 0-n relation so one item can have 0...n categories and item in classified has different values but same categories. I think that the category_values might also be named as classified_category_values if that helps. Also making FK from classified to category table might make it easier to think but it is not needed for data integrity.
Calmar
A: 

Your design is very much tied to the underlying products. Also you are putting what appears to be mutually exclusive data in different columns (e.g. surely a house can't be both a villa and an aprtment?) I'd go with a much more generalized form, something like:

Category 
Classified
Poster

As in the OP, but with primary keys added/declared.

Then group all the category specific attributes into a single table - like

Std_Tags {id, category, tag}
{0,Cars,year}
{1,Cars,fuel}
{2,house,type}
{3,house,rooms}

With values in another table:

classified_tags {std_tags_id, classified_id, value}
{0,13356,2005}
{2,109,villa}
{0,153356,diesel}

This also simplifies the building of input forms becuase the template is explicitly stated also, by adding a table like:

Allowed_values {std_tags_id, value}
{1,diesel}
{1,petrol}
{1,LPG}
{2,Villa}
{2,Apartment}

Then much of the data entry could be done using drop-down lists, conforming to standard searches.

C.

symcbean