用于维护MIS中产品动态价格的数据库表设计

时间:2016-10-24 06:53:10

标签: mysql database software-design

我们正在为客户编写MIS代码。特定产品的价格经常变化,客户需要维持价格有效的价格和日期。有一个名为PRODUCT_PRICE的表来维护其DDL简单显示如下的价格。

CREATE TABLE `PRODUCT_PRICE` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', `product_id` bigint(20) NOT NULL DEFAULT 0 COMMENT 'product id', `price` bigint(20) NOT NULL DEFAULT 0 COMMENT 'price value in cent', `start_date` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'when this price takes effect', `del_flag` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT 'mark if logically deleted', `status` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '0 new, 1 wait for audit, 2 accepted, 3 rejected', PRIMARY KEY (`id`), ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='product price table'

请注意,DDL中没有end_date,因为它恰好是下一条记录start_date的前一天,如果没有下一条记录,则为无限。

在系统中,每当有人在系统中创建或编辑某些产品的价格时,信息将被发送给管理员进行审核和审核。除非管理员接受,否则更改不会生效。可以再次编辑通过审核和审核的PRODUCT_PRICE

问题在于,在我们的旧设计中,PRODUCT_PRICE的特定记录将立即更改,status字段翻转为0以等待审核和审核。 但这不是客户想要的。

新要求是,除非管理员接受新的pricestart_date,否则人们仍可以在有人编辑后查看通过审核的价格记录。

我们应该如何重构旧表设计以实现新的要求,即除非管理员接受更改,否则某个记录的更改不会立即生效。

经过讨论,我们找到了2个解决方案。

  • 每当有人更改系统中的PRODUCT_PRICE记录时,将创建包含新信息的行,并将其发送以进行审核。接受后,旧的将被删除。因此,应在表格中添加新列reference_id以标记某个旧记录以进行更改。

  • 创建新表PRODUCT_PRICE_TEMP以存储等待审核的所有新价格记录。接受后,更新PRODUCT_PRICE中的某个旧记录。此解决方案还需要列reference_id来引用PRODUCT_PRICE中的某一行,但我们无需删除PRODUCT_PRICE中的记录以更改值(仅更新)。

我们的新要求是否有更好的设计?

1 个答案:

答案 0 :(得分:0)

你的第一个解决方案就是它。

尝试从鸟类视图中查看问题,从数据库模型中抽象出来。每次价格变动系统都会创建产品价格项的新实例。 从用户的角度来看,这是一个变化,对于系统来说,它是一个新的实体。好像你已经想出来了。

更重要的是 - 让我警告你这样做:"旧的将被删除"。我认为背后的假设是产品价格开始日期可能是过去的。这是非常危险的,以后会引起可怕的并发症。 过去的价格变动必须是罕见的例外情况,而非正常情况

当然还是会发生因为人们会犯错误。对于这种关键(并且罕见!)情况,您需要给予一个或两个高级人员(或管理员/支持人员)在未经任何批准的情况下更改过去的价格的能力。可能直接在DB中。没有时间,公司每秒都在亏钱。通常,同一个人以后会处理错误定价对客户和账单的所有后果。即使在这种情况下,您也不应该编辑product_price中的行,将旧的行标记为无效并从过去开始创建新行。