1

在以下两种数据库布局之间进行选择时,我真的可以使用一些见解。

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 中的字段“期间”作为开票周期编号。第二种布局引入了一个专门用于发票的表格。

具体来说,在这个应用程序中,您会在什么时候看到 Layout #1 被破坏,或者随着数据量的增加,什么样的事情会变得越来越难?在 Layout #2 的情况下,增加的灵活性/复杂性在实际中意味着什么?对 30-60-90 老化有何影响?我相信这在某些时候是必要的。

更一般地说,这似乎是您是否通过表中的字段或全新表中的字段跟踪/控制某些东西的一般情况,但这并不是真正的规范化问题,是吗?你一般是怎么选择的?

4

3 回答 3

2

我不完全确定为什么将“句点”附加到项目而不是订单本身。布局#1 似乎暗示您可以拥有一个由“详细信息”组成的开放“订单”,这些“详细信息”可能会在几年内被添加和支付。这似乎是非常错误的,应该让会计成为一场噩梦。布局#2 也好不到哪里去。

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

关于发票。一个订单可能附有一张或多张发票。发票的目标是针对它们应用付款。对于小额交易,发票和订单之间存在一对一的关系。

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

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

如果你想更喜欢并支持更多的现实世界,那么你将另外有一个 Payments 表,其中存储了发票号码、收到(或退款)金额、收到日期、交易 ID 和支票号码。如果您走这条路线,请从 Invoice 表中删除这些字段。


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

于 2011-06-09T22:27:31.830 回答
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

===========

在上面,您打开一个“案例”并将其与客户相关联。在持续的基础上,一个或多个人将比林斯应用到案例中。

一旦账单开始日期和期间的组合已经过去,系统将创建一个新的发票,其中包含从账单表中复制的详细信息。它应该根据那些尚未计费的详细信息来执行此操作。开票后,您应该锁定账单记录以防将来更改。

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

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

于 2011-06-13T16:17:36.597 回答
1

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

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

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

于 2011-06-15T03:08:00.323 回答