A 2-way relationship (a database design flaw)

跟風遠走 提交于 2019-12-24 05:17:08

问题


I've two tables which are connected to each other through a one to many relation. the problem is that the referenced table also has a foreign key of the second table!

I know it's confusing, So I'll show you a simple design of my database:

Authors

AuthorId      Name       DefaultBookId (FK)
--------      -------    -------------
1             John       1
2             Mike       3
3             Mig        5

Books

BookId        Title            AuthorId (FK)
--------      -------          -------------
1             TitleInfo1       1
2             TitleInfo2       3
3             TitleInfo3       2
4             TitleInfo4       1
5             TitleInfo5       3
6             TitleInfo6       3
7             TitleInfo7       1

Of course I have to make the AuthorId in the books table a foreign key and that's the normal case, but now I need to set a default book for every author so I'll define a foreign key on a new column (DefaultBookId) to specify the default book for each writer.

Now, both tables are dependent on each other so I can't delete any item unless I remove the relation between them and it doesn't feel the right thing to do!

Any ideas on whether this design flawed or not and what can I do about it ?


回答1:


I would implement this with a 3rd table that joins the other two. You'd end up with:

Authors

AuthorId      Name   
--------      -------
1             John   
2             Mike   
3             Mig    

DefaultBook

AuthorId      DefaultBookId (FK)
--------      -------------
1             1
2             3
3             5

Books

BookId        Title            AuthorId (FK)
--------      -------          -------------
1             TitleInfo1       1
2             TitleInfo2       3
3             TitleInfo3       2
4             TitleInfo4       1
5             TitleInfo5       3

By putting a UNIQUE constraing on DefaultBook.AuthorId you can prevent each author from having more than one default. If you need to delete an author, simply delete his default and any books associated with him, then you can delete the author.

The one problem this has is that it's hard to enforce that each author has a default book, but that requirement is what led you to this problem in the first place.




回答2:


You could remove DefaultBookId from Authors, add an IsDefaultForAuthor column to Books, and then apply a constraint such that each author only has one book marked as IsDefaultForAuthor.

Of course, this doesn't address issues such as books which are authored by multiple Authors, but I'm assuming that this is a toy example you're presenting, rather than your actual system being modelled.




回答3:


In principle this design is ok, but of course you have already found a problem in praxis.

Here are some things you can try:

  • if your database supports it (oracle does) make your constraints deferred. This will only check the constraints on commit, so you can delete a book and its author in one transaction. (con: very database specific)

  • instead of the authors.defaultBookId use a books.isAuthorsDefaultBook. (con: hard to enforce exactly one default book per Author; should be possible with FunctionBased Indexes indexes and/or materialized views, which probably are db dependend)

  • drop the not null constraint on defaultBookId and trust your application to do it right (con: loosing some of the powers of a database)

Clarification:

Dropping the the not null constraint on defaultBookId allows to set it to null, remove the formerly referenced book, then remove the author. For creation the same works, but in opposite order.



来源:https://stackoverflow.com/questions/5244920/a-2-way-relationship-a-database-design-flaw

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!