我有一个客户可以购买订阅的网站 客户可以随时查看付款记录,看看本已购买的商品。
我试图设计数据库来创建发票,但有些事情似乎不适合我。
我目前的设置如下:
+-----------+--------------+---------+
| Invoice | invoice_item | product |
+-----------+--------------+---------+
| id | id | id |
| fk_userID | desc | name |
| | quantity | price |
| | sum | |
| | fk_invoiceID | |
+-----------+--------------+---------+
invoice_item
有一个引用product
的外键似乎合乎逻辑
但是如果删除产品会发生什么?如果它们是相关的,那么item_list中的行将被删除或设置为null。
如果您想查看旧发票并且产品不再可用,那么这将无效。
那么,Product
和Item_list
应该相关吗?
答案 0 :(得分:5)
一旦定义了产品,就无法将其删除,因此在产品中添加一个Status字段 - 在本例中我使用枚举,尽管它很容易成为INT或一组bool(即Archived) ,我使用Parameter Enumeration Tables,但这是一个单独的答案。
最重要的是确保发票行在订单时具有从产品中获得的定价(和描述),以确保未来的任何定价更改或产品名称更改不会影响预先存在的发票
我使用的另一种技术(非常成功)是在数据库中引入 supersceding 实体的概念 - 这样原始记录就会保留,并且每当数据发生变化时都会插入新版本。为此,我添加以下字段:
它使查询更加麻烦 - 但特别是对于地址而言,必须确保发票保持不变并且地址变更不会反映在发票中 - 例如更改公司名称不应更改以前提出的发票。
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`);
答案 1 :(得分:0)
您只需在产品表中添加一个名为no_of_stock的列。如果产品在库存中为空或当前未使用,则不应删除,而是将该列的值设置为0.这意味着虽然产品目前不能销售,但之前已售出,但过去存在
答案 2 :(得分:0)
如果您希望人们能够查看旧发票,无论多久以前生成发票,并包含所有信息,那么您都不应该删除产品。只需添加一个包含ENUM('active', 'inactive') NOT NULL
或类似内容的列,即可将您当前提供的产品与仅保留旧产品的产品区分开来。