库的数据库模式

时间:2010-05-19 23:13:24

标签: database-design

我正在为我所在大学的某个部门设计一个图书馆管理系统,我想着眼于我提出的架构。这篇文章主要关注我们如何存储每本书的多个副本;关于我设计的东西让我误解了,我希望你们都能指出解决问题的更好方法。

为了处理查看图书的用户,我设计了三个表:预订客户 book_copy 。这些表之间的关系如下:

  • 每本图书都有许多 book_copies (以避免在存储我们拥有该图书的多个副本的情况下重复图书的信息)。
  • 每个用户都有很多 book_copies (关系的另一端)

表格本身的设计如下:

------------------------------------------------
book
------------------------------------------------
+ id
+ title
+ author
+ isbn
+ etc.
------------------------------------------------

------------------------------------------------
customer
------------------------------------------------
+ id
+ first_name
+ first_name
+ email
+ address
+ city
+ state
+ zip
+ etc.
------------------------------------------------

------------------------------------------------
book_copy
------------------------------------------------
+ id
+ book_id (FK to book)
+ customer_id (FK to customer)
+ checked_out
+ due_date
+ etc.
------------------------------------------------

关于这一点似乎不正确(或者至少对我来说效率低下) - 我身上的完美主义者感觉我没有正确地正常化这些数据。你说什么?是否有更好,更有效的方法来设计此架构?

谢谢!

4 个答案:

答案 0 :(得分:5)

这是一个OK架构。但是,它没有模拟工作可以有多个不同的演示文稿的可能性 - 也就是说,一本书可以有许多版本(以及翻译和格式)。

如何对此进行切片 - 您使用的粒度 - 与数据建模一样,取决于您的使用情况。换句话说,对于您来说,对于您来说, Alice in Wonderland 的德语翻译与英语orioginal“不同”,这是“真实的”吗? (应该是)。平装版是否与精装版“不同”?

对此的简单回答是只使用ISBN作为关键 - 让出版业为您做出这些决定。然后,具有相同ISBN的任何东西都是相同的并且是可互换的。

您可能还想要建模“可接受的替代品”之类的东西,“这个ISBN是可接受的替代品,因为唯一的区别是绑定”或“这个ISBN(达尔文的起源第6版)是那个的第六版(达尔文的原始物种的起源)“,或”这个ISBN是那个的翻译“甚至”这个ISBN(KJV圣经)是< em>类似那个(NIV圣经)。“这进入了微妙的层次。

另一个更基本的问题是,同一本书的副本与这些副本的签出混在一起。如果你不幸订购了10份,比如Herb Schildt的 The Annotated ANSI C Standard ,但是他们很幸运没有签出,因为你们大学的学生读过Pete Seebach对那本可怕的书的精彩评论,什么是book_copy中的那些副本的customer_id?

你想要(至少)书的表(work,isbn);复制;用户;以及user-checksout-copy的关系。

答案 1 :(得分:5)

有几件事。

我认为唯一明显的规范化错误是tpdi指出的错误:你不应该将book_copy实体与结帐记录结合起来。结帐应记录在一个单独的表中,该表将客户交叉引用到book_copy:


结帐

  • customer_id(FK:customer.id)
  • book_copy_id(FK:book_copy.id)
  • date_checked_out

您在此表中并不严格需要due_date,因为您始终可以通过查看date_checked_out并添加允许签出的标题来计算截止日期。这提出了具有各种媒体类型和不同结帐限制的主题。例如,DVD可能有1周的限制,而书籍有2周的限制。要跟踪此信息,您还有另一个表:


checkout_limit

  • 媒体类型
  • checkout_limit_days

如果你有多种类型的媒体可用,那么当然你必须考虑是否需要更多的表(每种媒体类型一个)或者想要同一个表中的所有媒体类型(然后你必须将它从“书”重命名为通用的)。在后一种情况下,您将有一些冗余,因为某些类型的媒体不具有其他类型的属性(例如,书籍有ISBN但DVD没有)。

答案 2 :(得分:1)

这些书籍的主表格titles怎么样呢?正如tpdi所建议的那样,它可以用来标记ISBN号,其中包含标题,作者和其他细节。然后,子表book可以是实际库存的列表,其中每个副本都有一个主键(如果您有10个带注释的ANSI C标准的副本,则为10个条目) titles表的关键字,它将这些副本链接到适当的标题和ISBN号。最后,checkout表将是您的多对多关系,其中用户的ID与书的ID(而不是标题)相关联。

到目前为止,您完成此操作的方式与我的建议之间的主要区别在于您已将customer_id移出书表并使用了新的结帐表。你仍然可以拥有每本书的日期时间,显示它是否已经出局,但要找出它的借出对象,你必须查阅结帐表。

答案 3 :(得分:0)

我认为他想要做的是简化他查询任何可用书籍副本的方式 假设Herb Schildt的 The Annotated ANSI C Standard 有10份, book_copy 表中将有10条记录。
我对吗? 因此,当学生签出书籍时,特别是复制#3,他就可以放置学生的customer_id。
其他9条记录仍然有一个空的customer_id 这肯定会使您的查询更容易,但这不是正确的做法 这是正确的,其他人指出,你需要某种交易表,结账表,以跟踪任何书出去。