2012-07-12 91 views
2

我有一个网站,客户可以购买订阅。
客户可以随时查看付款记录并查看买了什么。需要帮助设计我的发票数据库结构

我试图设计数据库创建发票,但有些东西似乎并不适合我。

我目前的设置是这样的:

+-----------+--------------+---------+ 
| Invoice | invoice_item | product | 
+-----------+--------------+---------+ 
| id  | id   | id  | 
| fk_userID | desc   | name | 
|   | quantity  | price | 
|   | sum   |   | 
|   | fk_invoiceID |   | 
+-----------+--------------+---------+ 

这似乎是合乎逻辑invoice_item具有参考product的外键。
但是,如果产品被删除会发生什么?如果它们相关,那么item_list中的行将被删除或设置为null。

如果您想查看旧发票并且该产品不再可用,那么这将不起作用。

那么,ProductItem_list应该有关系吗?

+0

不要删除您的产品。具有from_date和(可空)to_date,并且如果to_date不为null,则不显示它们。 – 2012-07-13 03:45:17

回答

4

一旦定义产品,您就不能删除产品,因此添加一个状态字段到产品 - 在这个例子中我使用了一个枚举,虽然它可以很容易地是一个INT或一组布尔(即存档),我用Parameter Enumeration Tables这个,但这是一个单独的答案。

最重要的是确保发票行在订单点具有从产品取得的定价(和描述),以确保未来的定价更改或产品名称更改不会影响预先存在的发票。我已经使用过的其他技术(相当成功)是在数据库中引入实体的实体概念 - 以便原始记录保持不变,并在数据发生更改时插入新版本。要做到这一点,我添加了以下字段:

  • currentID
  • supersededById
  • previousId

它使查询有点更麻烦 - 但尤其是对的地址是必不可少的保证发票保持不变,并且地址更改不会反映在发票中 - 例如更改公司名称不应更改以前提出的发票。

enter image description here

CREATE TABLE `Invoice` (
`id` INTEGER NOT NULL AUTO_INCREMENT , 
PRIMARY KEY (`id`) 
); 

CREATE TABLE `Invoice Item` (
`id` INTEGER NOT NULL AUTO_INCREMENT , 
`desc` VARCHAR(200) NOT NULL , 
`value` DECIMAL(11,3) NOT NULL , 
`quantity` DECIMAL(11,3) NOT NULL , 
`total` DECIMAL(11,3) NOT NULL , 
`fk_id_Invoice` INTEGER NOT NULL , 
`fk_id_Product` INTEGER NOT NULL , 
PRIMARY KEY (`id`) 
); 

CREATE TABLE `Product` (
`id` INTEGER NOT NULL AUTO_INCREMENT , 
`Price` DECIMAL(11,3) NOT NULL , 
`Name` VARCHAR(200) NOT NULL , 
`Status` ENUM NOT NULL , 
PRIMARY KEY (`id`) 
); 

ALTER TABLE `Invoice Item` ADD FOREIGN KEY (fk_id_Invoice) REFERENCES `Invoice` (`id`); 
ALTER TABLE `Invoice Item` ADD FOREIGN KEY (fk_id_Product) REFERENCES `Product` (`id`); 
+0

非常感谢您的回答。地址永远不会在我的地址表中被删除。因此,如果客户更改帐单地址,则会使用新的ID :) – Steven 2012-07-12 12:11:07

+0

@Steven出色 - 这是实现它的唯一方法。 – 2012-07-12 13:35:07

+0

你用什么工具来改善图像? – 2012-07-13 13:03:10

0

您只需要在产品表中添加一列作为no_of_stock。如果产品在库存中为空或当前未使用,则不应删除,而应将该列的值设置为0.这将意味着虽然产品目前不能销售,但之前已售出,过去已经存在

+0

感谢您的反馈。这样做是正常的吗? – Steven 2012-07-12 10:47:46

+0

是的,这是绝对正常的队友:-) – 2012-07-12 15:36:42

0

如果您希望人们能够看到他们的旧发票,无论他们生成了多久以前,并且包括所有信息,那么您都不应删除产品。只需添加一个包含ENUM('active', 'inactive') NOT NULL或其他类似列的列,以区分您目前提供的产品与那些您只保留旧参考的产品。

+0

对@Sashi Kant的答复与此相似。所以这个解决方案是标准的 – Steven 2012-07-12 10:49:17