0

我刚刚开始学习数据库设计。对于我的第一个项目,我用 padrino 做了一个简单的博客,现在我想要一些对我来说更具挑战性的东西。由于我有点书迷,我的朋友总是要求我向他们借书。所以很自然地,在任何给定的时间,我都会有很多书在四处飘荡。

现在我想要一个可以让我跟踪书籍的应用程序,即:每个朋友都有一个»Account«,我有很多»Books«,我的朋友可以在任何给定时间段内租用书籍。但我不完全确定如何对不同模型之间的关联进行建模。

class Friend
  include DataMapper::Resource

  property :id, Serial
  property :name, String
  property :surname, String

  has n, :loans
end

class Loan
  include DataMapper::Resource

  property :id, Serial
  property :started_at, Date
  property :returned_at, Date

  belongs_to :friend
  has n, :books
end

class Author
  include DataMapper::Resource

  property :id, Serial
  property :name, String
  property :surname, Integer

  has n, :books
end

class Book
  include DataMapper::Resource

  property :id, Serial
  property :title, String
  property :year, Integer
  property :returned, Boolean

  belongs_to :author
  belongs_to :loan
end

如果您能告诉我这个设计是否走在正确的轨道上,或者指出可以帮助我的资源,我将不胜感激。我怎样才能有效地管理一本书“消失”,然后又可以出租?

谢谢

4

1 回答 1

1

您当前的数据模型将有一个主要缺陷 - 即,书籍必须同时归还(嗯,不是真的,而是Loan第一本书归还时的“returned_at”,还是最后一本书?)。

Friend和之间也有一些脱节Author——如果朋友成为作者(或作者成为朋友)会发生什么?它们最终会出现在您的数据库中两次,这是一个问题。

以下是我将如何启动您的图书馆数据库(即使您只借给朋友也是如此)。我对数据映射器一无所知,所以这些本身就是表格设计。

Person
==========
id  -- autoincrement
fullname  -- varchar(128) - names are tricky, keep it simple here
nickname  -- varchar(15), nullable - optional

Book
=========
id  -- autoincrement
isbn  -- char(16) - check length, though
title  -- varchar(128) - this only works with single-language libraries
yearPublished  -- integer

Book_Author
=============
bookId  -- fk reference to book.id
authorId  -- fk reference to person.id

Subject
==========
id  -- autoincrement
subject  -- varchar(16)
description -- varchar(256)

Book_Subject
===============
bookId  -- fk reference to book.id
subjectId  -- fk reference to subject.id

Checkout
===============
id  -- autoincrement
occuredAt  -- timestamp, UTC if possible (or capture timezone)
bookId  -- fk reference to book.id
personId  -- fk reference to person.id

Checkin
==============
id  -- autoincrement
occuredAt  -- timestamp, UTC if possible (or capture timezone)
bookId  -- fk reference to book.id

然后,您可以通过哪些书籍的Checkin记录晚于所有Checkout记录来判断您当前手头有哪些书籍。


编辑:

要“批量”结帐/插入,请将Checkout/替换Checkin为以下版本:

Checkout
===============
id  -- autoincrement
occuredAt  -- timestamp, UTC if possible (or capture timezone)
personId  -- fk reference to person.id

Checkin 
============
id  -- autoincrement
occuredAt  -- timestamp, UTC if possible (or capture timezone)

Checkout_Book
==================
checkoutId  -- fk reference to Checkout.id
bookId  -- fk reference to Book.id

Checkin_Book
==================
checkinId  -- fk reference to Checkin.id
bookId  -- fk reference to Book.id

请注意,您不想只添加_Book表 - 您还需要从事务表中删除 fk 引用,否则您会冒一些令人讨厌的重复条目的风险。

于 2012-02-23T16:51:41.610 回答