使用字段还是全新表?

时间:2011-06-09 22:13:48

标签: database database-design invoice

我真的可以使用一些见解来选择以下两种数据库布局。

Layout #1          | Layout #2  
                   |  
CUSTOMERS          | CUSTOMERS  
 id int pk         |  id int pk  
 info char         |  info char  
                   |  
ORDERS             | ORDERS  
 id int pk         |  id int pk  
 customerid int fk |  customerid int fk  
 date timedate     |  date timedate  
                   |  
DETAILS            | INVOICES  
 id int pk         |  id int pk  
 orderid int fk    |  orderid int fk  
 date timedate     |  date timedate  
 description char  |  
 amount real       | DETAILS  
 period int        |  id int pk  
                   |  invoiceid int fk  
                   |  date timedate  
                   |  description char  
                   |  amount real  

这是针对小型企业,独资经营者的结算申请。第一个布局没有单独的发票表,而是依赖于DETAILS中的字段'period'作为结算周期号。第二种布局引入了专门用于发票的表格。

特别是在这个应用程序中,您在什么时候看到布局#1中断,或者随着数据量的增加会变得越来越难?在布局#2的情况下,实际上增加的灵活性/复杂性意味着什么?对30-60-90衰老有什么影响?我相信在某些时候这是必要的。

更一般地说,这似乎是通过表格或整个新表中的字段跟踪/控制某些内容的一般情况,但它不是真正的规范化问题,是吗?你一般如何做出选择?

3 个答案:

答案 0 :(得分:2)

我不完全确定为什么“期间”附加到项目而不是订单本身。布局#1似乎意味着您可以拥有一个由“细节”组成的开放式“订单”,这些“细节”可能会在一段时间内添加和支付。这似乎非常错误,应该使会计成为一场噩梦。布局#2真的不是更好。

一般而言,订单由具有购买或合同日期的单笔交易组成。该事务可能包含多个详细信息项,但它仍然是一个事务。它代表买方和卖方之间某个时间点达成的单一协议。如果购买了新商品,则会创建新订单...考虑到这一点,表格结构都不起作用。

关于发票。订单可能附有一个或多个发票。发票的目标是对其进行付款。对于小型交易,发票和订单之间存在一对一的关系。

在较大的交易中,您可能会有多个发票应用于单个订单。例如,如果您已签订合同,可以“轻松支付199.99美元......”。在这种情况下,您将有3张发票,每张199.99美元,适用于单笔订单,总额为599.97美元;并且每个都在不同的时间段到期。

发票表应至少包含订单ID,发票编号,发票日期,开票金额,到期日,交易ID(信用卡),支票号(明显),收到金额和收到日期字段。

如果您希望得到更多的真实世界,那么您还需要一个付款表,其中存储了发票号,收到的金额(或已退款),收到的日期,交易ID和支票号。如果您选择此路线,请从“发票”表中删除这些字段。


现在,如果您需要支持经常性费用(例如,互联网托管),那么您将拥有一个名为“Contracts”和“ContractDetails”的类似表格。这些表格将存储合约详细信息(类似于订单和订单详细信息,但包括日期开始,日期结束和重复周期)。当下一个结算周期被点击时,详细信息将用于创建订单并生成相应的发票。

答案 1 :(得分:2)

鉴于以前的评论,这就是我接近它的方式:

CUSTOMERS
  id int pk
  info char

CASES
  id int pk
  customerid int fk
  dateOpened datetime
  dateClosed datetime
  status int <- open, closed, final billed, etc.
  BillPeriod int <- here is where you determine how often to bill the client.
  BillStartDate datetime <- date that billings should start on.

BILLING
  billingid int pk
  caseid int fk
  userid int fk <- id of person who is charging to this case. i.e. the lawyer.
  invoicedetailid fk <- nullable, this will make it easier to determine if this particular item has been invoiced or not.
  amount money
  billdate datetime
  billingcode int fk <- associate with some type of billing code table so you know what this is: time, materials, etc.
  description char


INVOICES
  invoiceid int pk
  customerid int FK
  invoicedate datetime
  amount money <- sum of all invoice details
  status int <- paid, unpaid, collection, etc..
  discount money <- sum of all invoice details discounts
  invoicetotal <- usually amount - discount.

INVOICEDETAILS
  invoicedetailid int PK
  invoiceid int FK
  billingid int FK
  discount money <- amount of a discount, if any

===========

在上面,您打开一个“案例”并将其与客户关联。在持续的基础上,一个或多个人将Billings应用于案件。

一旦账单开始日期和期间的组合已经过去,系统将创建一个新的发票,其中包含从结算表中复制的详细信息。它应该基于那些尚未结算的细节来做到这一点。一旦开具发票,您应该锁定未来更改的结算记录。

如果您需要不同的触发器,则可能必须将“BillPeriod”更改为其他类型的字段。例如,句点只是创建发票的一个“触发器”。

可能包括当您达到一定金额时发送发票。这可以在客户或案例级别进行配置。另一种选择是限制支出。例如,将一个上限值放在案件级别,以防止账单超过上限;或者至少导致警报被发送给相关方。

答案 2 :(得分:1)

由于您正在进行合法结算,我建议您花一些时间查看Sage Timeslips的功能。律师的行为不像其他人; lawywers的会计软件不像其他会计软件那样。这是业务的本质。

他们有30天的免费试用版,你可以从帮助文件和文档中学到很多东西。

此外,从用户界面逆向工程数据库设计是一种很好的做法。