views:

911

answers:

6

I currently have multiple tables in my database which consist of the same 'basic fields' like:

name character varying(100),
description text,
url character varying(255)

But I have multiple specializations of that basic table, which is for example that tv_series has the fields season, episode, airing, while the movies table has release_date, budget etc.

Now at first this is not a problem, but I want to create a second table, called linkgroups with a Foreign Key to these specialized tables. That means I would somehow have to normalize it within itself.

One way of solving this I have heard of is to normalize it with a key-value-pair-table, but I do not like that idea since it is kind of a 'database-within-a-database' scheme, I do not have a way to require certain keys/fields nor require a special type, and it would be a huge pain to fetch and order the data later.

So I am looking for a way now to 'share' a Primary Key between multiple tables or even better: a way to normalize it by having a general table and multiple specialized tables.

+1  A: 

You could create one table with the main fields plus a uid then extension tables with the same uid for each specific case. To query these like separate tables you could create views.

Chris Simpson
+5  A: 

Consider using a main basic data table with tables extending off of it with specialized information.

Ex.

basic_data
id int,
name character varying(100),
description text,
url character varying(255)


tv_series
id int,
BDID int, --foreign key to basic_data
season,
episode
airing


movies
id int,
BDID int, --foreign key to basic_data
release_data
budget
Jay S
Thanks, I have already thought of that before, the only problem I have had with this is that it theoretically gives the possibiltiy to have multiple entries in the tables for one in basic_data (i.e. there could be an entry in tv_series and movies). If nothing better comes, Ill do it this way.
Patrick Daryll Glandien
And also this is a unidirectional relationship since only the specialized tables point to the general table.
Patrick Daryll Glandien
Up vote, although I'd suggest that you be careful with the "basic_data" table not to make it too generic. If it's "media" or something like that it makes sense. Don't try to force things into it that don't make sense though.
Tom H.
Yes, this is what I tried to say below but obviously used far too few words. I'll be more verbose next time.
Chris Simpson
Having more than one entry relate to basic_data is the whole IDEA of relational databases. And it is not unidirectional -- it is bidirectional, but with a one-to-many relationship from the basic table to the leaf tables.
Joe
@Joe - I believe that the idea in this case is to subtype the "basic_data" table. It would be a 1:1 relationship, which should only exist in one other subtable, although I've seen other situations where allowing entries in multiple subtypes to be permitted too.
Tom H.
+1  A: 

What you are looking for is called 'disjoint subtypes' in the relational world. They are not supported in sql at the language level, but can be more or less implemented on top of sql.

mike g
+6  A: 

Right, the problem is you want only one object of one sub-type to reference any given row of the parent class. Starting from the example given by @Jay S, try this:

create table media_types (
  media_type     int primary key,
  media_name     varchar(20)
);
insert into media_types (media_type, media_name) values
  (2, 'TV series'),
  (3, 'movie');

create table media (
  media_id       int not null,
  media_type     not null,
  name character varchar(100),
  description    text,
  url character  varying(255),
  primary key (media_id, media_type),
  foreign key (media_type) 
    references media_types (media_type)
);

create table tv_series (
  media_id       int primary key,
  media_type     int check (media_type = 2),
  season         int,
  episode        int,
  airing         date,
  foreign key (media_id, media_type) 
    references media (media_id, media_type)
);

create table movies (
  media_id       int primary key,
  media_type     int check (media_type = 3),
  release_date   date,
  budget         numeric(9,2),
  foreign key (media_id, media_type) 
    references media (media_id, media_type)
);

This is an example of the disjoint subtypes mentioned by @mike g.

Bill Karwin
+1  A: 

Since you tagged this PostgreSQL, you could look at http://www.postgresql.org/docs/8.1/static/ddl-inherit.html but beware the caveats.

MkV
A: 

Using the disjoint subtype approach suggested by Bill Karwin, how would you do INSERTs and UPDATEs without having to do it in two steps?

Getting data, I can introduce a View that joins and selects based on specific media_type but AFAIK I cant update or insert into that view because it affects multiple tables (I am talking MS SQL Server here). Can this be done without doing two operations - and without a stored procedure, natually.

Thanks

Peter
Well, I guess, I could use an instead of trigger to make this work, but it means I would have to code these up for each sub-type I have. And also, I think triggers are so "secret" when debugging... Is there a better way?
Peter