Tengo dos tablas libros y audiolibros, que tienen ISBN como claves principales. Tengo una tabla por escrito que tiene un atributo isbn que tiene una restricción de clave externa para Libros y Audiolibros ISBN. El problema que surge cuando inserto en el escrito es que postgresql quiere que el ISBN que inserto en escritoby esté en ambos libros y audiolibros. Tiene sentido para mí tener una tabla escrita por eso almacena autores y los libros/audiolibros que han escrito, sin embargo, esto no se traduce en una tabla en postgresql. La solución alternativa que estoy pensando implementar es tener dos nuevas relaciones, audiobook_writtenby y books_writtenby, pero no estoy seguro de que sea una buena alternativa. ¿Podría darme una idea de cómo implementaría mi idea original de tener una sola tabla escrita haciendo referencia a dos tablas diferentes o cómo podría diseñar mejor mi base de datos? Déjeme saber si usted necesita más información.POSTGRESQL Clave externa que hace referencia a las claves principales de dos tablas diferentes
Respuesta
RDBMS no admiten restricciones de clave externa polimórficas. Lo que quiere hacer es razonable, pero no algo acomodado por el modelo relacional y uno de los problemas reales de la desigualdad de impedancia relacional del objeto al hacer sistemas ORM. Nice discussion on this on Ward's WIki
Un enfoque para su problema podría ser crear una tabla separada, información conocida, y configurar restricciones y/o desencadenantes en libros y audiolibros para que la tabla contenga todos los íconos válidos de ambas tablas de libros específicos. Entonces su restricción de FK en escritoby se comparará con known_isbns.
Puede usar la herencia de tablas para obtener lo mejor de ambos mundos. Crea el audiobook_writtenby y books_writtenby con una cláusula INHERITS
que hace referencia a la tabla writtenby. Las claves foráneas podrían definirse en el nivel secundario como usted describe, pero aún podría hacer referencia a los datos en el nivel superior. (También puede hacer esto con una vista, pero suena como herencia podría ser más limpio en este caso.)
Consulte los documentos:
http://www.postgresql.org/docs/current/interactive/sql-createtable.html
http://www.postgresql.org/docs/current/interactive/tutorial-inheritance.html
http://www.postgresql.org/docs/current/interactive/ddl-inherit.html
Tenga en cuenta que es probable que desee agregar un desencadenante ANTES DE INSERTAR en la tabla writeby si hace esto.
Hay más de una forma de hacer esto en PostgreSQL. Personalmente, prefiero de esta manera.
-- This table should contain all the columns common to both
-- audio books and printed books.
create table books (
isbn char(13) primary key,
title varchar(100) not null,
book_type char(1) not null default 'p'
check(book_type in ('a', 'p')),
-- This unique constraint lets the tables books_printed and books_audio
-- target the isbn *and* the type in a foreign key constraint.
-- This prevents you from having an audio book in this table
-- linked to a printed book in another table.
unique (isbn, book_type)
);
-- Columns unique to printed books.
create table books_printed (
isbn char(13) primary key references books (isbn),
-- Allows only one value. This plus the FK constraint below guarantee
-- that this row will relate to a printed book row, not an audio book
-- row, in the table books. The table "books_audio" is similar.
book_type char(1) default 'p'
check (book_type = 'p'),
foreign key (isbn, book_type) references books (isbn, book_type),
other_columns_for_printed_books char(1) default '?'
);
-- Columns unique to audio books.
create table books_audio (
isbn char(13) primary key references books (isbn),
book_type char(1) default 'a'
check (book_type = 'a'),
foreign key (isbn, book_type) references books (isbn, book_type),
other_columns_for_audio_books char(1) default '?'
);
-- Authors are common to both audio and printed books, so the isbn here
-- references the table of books.
create table book_authors (
isbn char(13) not null references books (isbn),
author_id integer not null references authors (author_id), -- not shown
primary key (isbn, author_id)
);
En este ejemplo específico, no es necesario utilizar varias tablas. Simplemente use la tabla "Libro" y agregue las columnas de "AudioBook", si corresponde. Si tiene que diferenciarse en el nivel de la tabla con columnas muy específicas, cree vistas. ¿Has verificado si un "Libro" y un "Libro de audio" con el mismo contenido tienen el mismo ISBN?
Aunque su respuesta es técnicamente correcta, no creo que deba seguirse. PostgreSQL permite modelar esto bastante bien. Plegar múltiples objetos en una sola mesa generalmente termina en un gran desastre. – Theuni
- 1. ¿Clave externa que se refiere a claves principales en varias tablas?
- 2. Referencia dos ensamblados iguales, solo las claves públicas son diferentes
- 3. ¿Cómo puedo crear una clave externa que hace referencia a una clave compuesta entero?
- 4. clave externa condicional PostgreSQL
- 5. clave externa a varias tablas
- 6. ¿Clave externa a una de muchas tablas?
- 7. Unir tablas, clave externa
- 8. Clave primaria compuesta, clave externa. ¿Referencia a objeto o clave?
- 9. Una restricción que solo permite que una de dos tablas haga referencia a una tabla base
- 10. Uso de DbUnit con tablas que no tienen claves principales
- 11. clave externa que hace referencia una clave principal 2 columnas en SQL Server
- 12. Crear una clave externa a las tablas del sistema
- 13. Oracle todas las referencias de clave externa
- 14. Clave principal de actualización del Servidor SQL que también es una clave externa en dos tablas
- 15. Dos claves externas que hacen referencia a la misma clave primaria
- 16. Legit? Dos claves externas que hacen referencia a la misma clave primaria
- 17. uniendo dos tablas con una clave externa con nulo?
- 18. Referencia de clave externa a la tabla en otro esquema
- 19. ¿Cómo agregar datos a dos tablas vinculadas mediante una clave externa?
- 20. ¿la clave externa siempre hace referencia a una clave única en otra tabla?
- 21. Servidor SQL: ver todas las dependencias de la clave externa
- 22. ¿Cómo encontrar todas las tablas que tienen claves foráneas que hacen referencia a table.column particular y tienen valores para esas claves foráneas?
- 23. ¿Clave externa de columna múltiple en MySQL?
- 24. Tablas de base de datos, una tabla que hace referencia a varias tablas no relacionadas
- 25. PostgreSQL: ¿Cómo indexar todas las claves externas?
- 26. ¿Una o dos claves principales en la tabla de muchos a muchos?
- 27. clave externa MySQL InnoDB entre diferentes bases de datos
- 28. consulta SQLite para encontrar las claves principales
- 29. ¿Cómo se combinan las tablas con las claves principales del autonumber?
- 30. externa hace referencia DTD en XML
El modelo relacional y las bases de datos SQL realmente manejan bien este tipo de cosas. El problema no es relacional o SQL; el problema es que una de las restricciones obvias se implementa incorrectamente. (La restricción es que los ISBN para libros y audiolibros proceden del mismo dominio.) –