views:

52

answers:

3

I am designing a data model for tourism-site. I have a table for places (countries, resorts, hotels) and a table for tours. The tables are pretty different in fields so the cant be merged into one. Both of them have usual auto_increment as id. Places and tours have photos so there is a third table for photos. This table has 'parent' field in which I plan to store the parent (place or tour) id.

Which is the best way to design these tables? One table for all photos and two tables as 'parents' for the photos. For now I have added 'parent_type' column to photos table, so when my script displays a tour *it calls photos by its (parent) id and type (parent_type) 'tour' from the photos table*...

Upd: Is there a more graceful solution? With just 3 tables and no 'parent_type' column?

(cant post a diagram... here's the link http://share.xmind.net/yentsun/tourism-site-data-model/)

A: 

I had the same situation a while ago. I used a 'set' type for the parent_type. Never store names for your type, use integers because they can be read much faster. And also place indexes on your foreign keys.

Ben Fransen
Thanks, Ben - yeah, I used integers of course. I wonder how do I implement foreign indexes here?
yentsun
Never used them before, so its a bit complicated. And I guess they wont help me to get rid of 'parent_type' column... I though I could use unique ids over two tables (places and tours) and photos would have just one 'parent' column
yentsun
I just placed an index on the FK column, so it can be read faster.
Ben Fransen
+2  A: 

Country, hotel and resort are sub-type of a place. The place table contains all fields common to places, while country, hotel and resort tables contain fields specific to each one. One tour contains many places, one place can be a part of many tours.

alt text

Here is example code for Place and Country -- it is T-SQL, but you'll get the idea.

CREATE TABLE Place
( 
    PlaceID        int  NOT NULL ,
    Type                varchar(2) 
);

ALTER TABLE Place
ADD CONSTRAINT PK_Place PRIMARY KEY  CLUSTERED (PlaceID ASC)
;
ALTER TABLE Place
ADD CONSTRAINT FK1_Place FOREIGN KEY (ParentID) REFERENCES Place(PlaceID)
;

CREATE TABLE Country
( 
    PlaceID        int  NOT NULL 
);

ALTER TABLE Country
ADD CONSTRAINT PK_Country PRIMARY KEY  CLUSTERED (PlaceID ASC)
;
ALTER TABLE Country
ADD  CONSTRAINT FK1_Country FOREIGN KEY (PlaceID) REFERENCES Place(PlaceID)
     ON DELETE CASCADE
     ON UPDATE CASCADE
;

UPDATE after comment
Sorry, four tables is my best for this one.

alt text

Damir Sudarevic
+1 for the diagram
knittl
Thanks for the diagram Damir! But is this really the most optimal way of organizing my model? I had three tables and one additional column (parent_type, which I would consider unnecessary). With your solution I have... 7 tables? Maybe I asked the question wrongly. Its not about indexes or foreign keys - its about minimum of tables and columns and joins. Is there a way to come up with only three tables and no additional columns to identify the parent of a photo?I'll update the question. Again, thanks, Damir!
yentsun
You can do 4 if (as in your original) hotel, resort and country are "pulled back" into place.
Damir Sudarevic
Thanks, Damir, you gave me the idea of how to use foreign keys.
yentsun
A: 

There are no Parents involved - you just have photos with two atttributes - Place and Tour.

So use a Photos table with two foreign keys, one for Tour, the other for Place. And then of course a Tours table and a Places table.

If you need to know which Tours went to which Places, deal with it directly with a Tour_Places table which justifies itself independently.

As for "Parentness", this solution still lets you identify, for a Tour (or Place), which Photos are associated.

le dorfier
Well! This solution seems like the most flexible! I can even have same photo for a place and a tour with it! Thanks, le doflier - I'll implement this one!
yentsun