Ste*_*ven 2 mysql database-design
我有一个网站,客户可以在那里购买订阅.
客户可以随时查看付款历史记录并查看已购买的商品.
我正在尝试设计用于创建发票的数据库,但有些东西似乎不适合我.
我目前的设置如下:
+-----------+--------------+---------+
| Invoice | invoice_item | product |
+-----------+--------------+---------+
| id | id | id |
| fk_userID | desc | name |
| | quantity | price |
| | sum | |
| | fk_invoiceID | |
+-----------+--------------+---------+
Run Code Online (Sandbox Code Playgroud)
invoice_item有一个外键引用似乎是合乎逻辑的product.
但是如果删除产品会发生什么?如果它们是相关的,则item_list中的行将被删除或设置为null.
如果您想查看旧发票并且产品不再可用,那么这将无效.
那么,应该Product和Item_list相关吗?
一旦定义了产品,就无法将其删除,因此在产品中添加一个Status字段 - 在本例中我使用枚举,尽管它可以很容易地是INT或一组bool(即Archived),我使用参数枚举表,但这是一个单独的答案.
最重要的是确保发票行具有从订单处的产品中获得的定价(和描述),以确保任何未来的定价更改或产品名称更改不会影响预先存在的发票.
我使用的另一种技术(非常成功)是在数据库中引入超级实体的概念- 这样原始记录就会保留,并且每当数据发生变化时都会插入新版本.为此,我添加以下字段:
它使查询更加麻烦 - 但特别是对于地址而言,必须确保发票保持不变并且地址变更不会反映在发票中 - 例如,更改公司名称不应更改以前提出的发票.

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`);
Run Code Online (Sandbox Code Playgroud)