使用datamapper进行简单的租赁数据库设计

时间:2012-02-23 15:29:56

标签: sql ruby datamapper model-associations

我刚开始学习数据库设计。对于我的第一个项目,我用padrino创建了一个简单的博客,现在我想要一些对我来说更具挑战性的东西。 由于我有点像书,我的朋友总是要我借书。所以很自然地,我在任何时候都会有很多书籍浮现。

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

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

如果你能告诉我我是否在使用这种设计的正确轨道上,或者可能指向可以帮助我的资源,我会很感激。 我怎样才能有效地管理一本书“已经消失”然后再次出租?

由于

1 个答案:

答案 0 :(得分:1)

您当前的数据模型将有一个主要缺陷 - 也就是说,书籍必须同时返回(好吧,不是真的,但是当第一本书回来时,Loan'return_at',或者在最后一个?)。

FriendAuthor之间也存在一些脱节 - 如果朋友成为作者(或作者成为朋友)会发生什么?他们最终会在你的数据库中两次,这是一个问题。

以下是我如何启动你的图书馆数据库(就是这样,即使你只是借给朋友)。我对datamapper一无所知,所以这些都是表格设计本身。

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引用,否则您会冒一些讨厌的重复条目。