relacional - programacion orientada a objetos con oracle pl/sql pdf
¿Polimorfismo en las tablas de la base de datos SQL? (7)
Actualmente tengo varias tablas en mi base de datos que constan de los mismos ''campos básicos'' como:
name character varying(100),
description text,
url character varying(255)
Pero tengo múltiples especializaciones de esa tabla básica, que es, por ejemplo, que tv_series
tiene los campos season
, episode
, airing
, mientras que la tabla de movies
tiene release_date
, budget
, etc.
Ahora, al principio, esto no es un problema, pero quiero crear una segunda tabla, llamada linkgroups
con una clave externa para estas tablas especializadas. Eso significa que de alguna manera tendría que normalizarlo dentro de sí mismo.
Una forma de resolver esto que he escuchado es normalizarlo con una key-value
-pair-table, pero no me gusta esa idea, ya que es una especie de esquema de ''base de datos dentro de una base de datos'', no lo hago. tener una forma de requerir ciertas claves / campos, ni requerir un tipo especial, y sería un gran dolor buscar y ordenar los datos más tarde.
Así que estoy buscando una forma de ''compartir'' una clave principal entre múltiples tablas o incluso mejor: una forma de normalizarlo teniendo una tabla general y varias tablas especializadas.
Como etiquetó este PostgreSQL, puede consultar http://www.postgresql.org/docs/8.1/static/ddl-inherit.html pero tenga cuidado con las advertencias.
Considere utilizar una tabla de datos básicos principal con tablas que se extienden con información especializada.
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
Correcto, el problema es que quiere que solo un objeto de un subtipo haga referencia a cualquier fila dada de la clase padre. A partir del example dado por @Jay S, intente esto:
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 varchar(100),
description text,
url varchar(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)
);
Este es un ejemplo de los subtipos disjuntos mentioned por @mike g.
Comentarios de @Countably Infinite y @Peter:
INSERTAR en dos tablas requeriría dos instrucciones de inserción. Pero eso también es cierto en SQL cada vez que tiene tablas secundarias. Es algo común de hacer.
ACTUALIZAR puede requerir dos instrucciones, pero algunas marcas de RDBMS admiten UPDATE multi-tabla con la sintaxis JOIN, por lo que puede hacerlo en una declaración.
Al consultar datos, puede hacerlo simplemente consultando la tabla de media
si solo necesita información sobre las columnas comunes:
SELECT name, url FROM media WHERE media_id = ?
Si sabe que está consultando una película, puede obtener información específica de la película con una sola combinación:
SELECT m.name, v.release_date
FROM media AS m
INNER JOIN movies AS v USING (media_id)
WHERE m.media_id = ?
Si desea información para una entrada de medios determinada, y no sabe de qué tipo es, debería unirse a todas las tablas de subtipos, sabiendo que solo una de esas tablas de subtipos coincidirá:
SELECT m.name, t.episode, v.release_date
FROM media AS m
LEFT OUTER JOIN tv_series AS t USING (media_id)
LEFT OUTER JOIN movies AS v USING (media_id)
WHERE m.media_id = ?
Si el medio dado es una película, entonces todas las columnas en t.*
Serán NULL.
La pregunta es bastante antigua, pero para las versiones postresql modernas también vale la pena considerar el uso del tipo json / jsonb / hstore. Por ejemplo:
create table some_table (
name character varying(100),
description text,
url character varying(255),
additional_data json
);
Lo que estás buscando se llama ''subtipos disjuntos'' en el mundo relacional. No son compatibles en sql en el nivel de idioma, pero se pueden implementar más o menos en la parte superior de sql .
Puede crear una tabla con los campos principales más un uid y luego tablas de extensión con el mismo uid para cada caso específico. Para consultar estos como tablas separadas, puede crear vistas.
Usando el enfoque de subtipo disjunto sugerido por Bill Karwin, ¿cómo harías INSERTES y ACTUALIZACIONES sin tener que hacerlo en dos pasos?
Obteniendo datos, puedo introducir una vista que se une y selecciona en función de un tipo de medio específico, pero AFAIK no puedo actualizar o insertar en esa vista porque afecta a varias tablas (estoy hablando de MS SQL Server aquí). ¿Se puede hacer esto sin hacer dos operaciones, y sin un procedimiento almacenado, naturalmente?
Gracias