我有两个表Books和Audiobooks,这两个表的主键都是ISBN,还有一个表writtenby
,它的isbn
属性对Books和Audiobooks的ISBN有一个外键约束。
当我插入到writtenby
中时出现的问题是postgresql希望我插入到writtenby
中的ISBN同时出现在书籍和有声读物中。
对我来说,有一个表writtenby
来存储作者和他们写的书/有声读物是有意义的,但是这并不能转化为postgresql中的表。
我正在考虑实现的替代解决方案是拥有两个新关系audiobook_writtenby
和books_writtenby
,但我不确定这是否是一个好的替代方案。
你能给予我如何实现我最初的想法,让一个表writtenby
引用两个不同的表,或者我如何更好地设计我的数据库吗?如果你需要更多的信息,请告诉我。
4条答案
按热度按时间soat7uwm1#
在PostgreSQL中有不止一种方法可以做到这一点。就我个人而言,我更喜欢这种方法。
qxsslcnc2#
你可以使用表继承来达到两全其美的效果。创建audiobook_writenby和books_writenby,并使用
INHERITS
子句引用writenby表。外键可以像你描述的那样定义在子级,但是你仍然可以在更高的级别引用数据。(你也可以使用视图来实现这一点,但是在这种情况下,听起来继承可能更干净。)参见文档:
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
注意,如果这样做,您可能需要在writenby表上添加一个BEFORE INSERT触发器。
ttcibm8c3#
RDBMS不支持多态外键约束。您想要做的是合理的,但关系模型不能很好地适应,并且在创建ORM系统时对象关系阻抗不匹配是一个真实的的问题。Nice discussion on this on Ward's WIki
解决问题的一种方法是创建一个单独的表known_isbns,并在Books和AudioBooks上设置约束和/或触发器,以便该表包含两个类型特定的book表的所有有效isbns。然后,writenby上的FK约束将检查known_isbns。
6yjfywim4#
在这个特定的例子中,绝对没有必要使用多个表。只要使用表“Book”,并添加“AudioBook”中的列(如果适用的话)。如果您必须在表级别上区分非常特定的列,请创建视图。您是否检查过内容相同的“Book”和“Audio Book”是否具有相同的ISBN?