如何将项目与定价数据正确关联,并将价格变化历史记录考虑在内

时间:2012-08-05 18:27:35

标签: database-design relational-database

事实上,所有POS系统都会在销售时将商品的价格直接记录到交易表中,因为该价格可能会在以后更改,但其售出的价格应保持不变。

我想知道如何设置保存价格变动历史的定价表,以便您可以根据商品和销售时间将交易与该表相关联,以便获得正确的价格。价格?

我认为任何曾经使用POS系统的人都会明白我在这里谈论的内容,但如果我的问题不清楚,请告诉我,我会尝试更好地解释。

我没有标记特定数据库,因为这个问题显然不是特定于某个特定数据库,但是因为我知道这是我将要问的第一个问题:SQL Server 2008。

编辑:

这是我刚才想到的一个解决方案,我希望得到一些反馈...

我想我的价格表可能有这样的字段: PriceId,ItemId,价格,日期

PriceId是自动编号,ItemId与Items表有关。现在,不是将实际价格保存到交易表,而是保存给定项目的最新PriceId。

思想?

3 个答案:

答案 0 :(得分:4)

我真的没有理由这样做。您正在为几乎所有分析目的和大多数查询添加额外的连接,这将影响应用程序的速度。

通过最简单的方式回答您的问题就是创建定价表,就像创建temporal database一样。

因此,做一些假设,您的定价表可能包含以下列:

id int, pk
product_id, fk into products
price_start_date date
price_end_date date
price number(x, 2)

假设您的“订单”表中包含订单发布/发布等的日期,无论您使用什么来确定价格每个查询以确定价格都将成为

select price
  from pricing p
  join orders o
    on o.order_Date between p.price_start_date and p.price_end_date

然而,正如我所说,我不会这样做。我能想到的唯一障碍是,在订单表中具有历史价格而不是单独的价格,这使得历史价格分析在数据库上稍微重一些。你不会经常这样做而不想知道已售出多少单位,因此无论如何都需要使用订单表,所以我认为它不会产生很大的影响。

我认为这是其中一个非常略微非规范化的数据库肯定是积极的而非负面的。


好的,关于你的编辑,我的建议几乎没有什么区别。我将假设您的表在itemid date上是唯一的(不要将其用作实际的列名称)否则日期可以在您的“项目”表中保持一致。

但是,它确实意味着无论何时向交易表中添加内容,您都必须使用汇总查询来计算每个项目的最新价格。我的建议使更新价格变得更加困难,但更容易计算出价格。当你更频繁地计算物品的价格而不是更新我个人的价格时,请按照我的建议来达到性能。

答案 1 :(得分:0)

我在上一个项目中遇到了这个问题,我决定使用价格表来保持历史价格,因为客户想要验证他的供应商改变价格等的频率。对于许多报告我发现自己做了额外的加入只是为了检索当前的价格感觉很麻烦,所以我最终得到了这样一张桌子。

product:
    name ...
    quantity ...
    ...
    priceId ... (foreign key to lastest price on prices table)
    price ... (the last updated price, to avoid the prices join)

答案 2 :(得分:0)

你必须根据你的情况进行调整,但在我的情况下,我有一个收费类型的查询表,这就是我如何将费用更新为新价格并保留原始价格以供参考。此视图的开销仅限于您经常查询它以生成发票。这是我的用例。

您可以在此处使用vwCharge获取最新定价的列表。当使用update_charge_rate()时,它会添加一个新的更新日期,查询vwCharge只会显示最新的日期。

分隔符设置为//

查找表:

CREATE TABLE lkCharge (
  charge_id SMALLINT NOT NULL AUTO_INCREMENT,
  charge_datecreated DATE NOT NULL,
  charge_name VARCHAR(20) NOT NULL,
  charge_rate DECIMAL(10,2) NOT NULL,
  charge_islocked CHAR(1) DEFAULT 'N',
  charge_lockedby VARCHAR(255) DEFAULT NULL,
  charge_lockdate TIMESTAMP NULL,
  charge_isdeleted CHAR(1) DEFAULT 'N',
  CONSTRAINT pkChargeId PRIMARY KEY(charge_id, charge_datecreated)
) ENGINE=InnoDB DEFAULT CHARSET=utf8//

观点:

CREATE VIEW vwCharge AS
  SELECT
    charge_id,
    charge_datecreated,
    charge_name,
    charge_rate,
    charge_islocked,
    charge_lockedby,
    charge_lockdate,
    charge_isdeleted
  FROM lkCharge AS o
  WHERE o.charge_id=o.charge_id AND charge_datecreated=(
    SELECT MAX(charge_datecreated)
      FROM lkCharge AS i
        WHERE i.charge_id=o.charge_id
  )//

更新程序:

CREATE PROCEDURE update_charge_rate(
  IN p_charge_id SMALLINT,
  IN p_new_charge_rate DECIMAL(10,2)
)
BEGIN
  DECLARE _name VARCHAR(20);

  SELECT charge_name INTO _name
    FROM vwCharge WHERE charge_id=p_charge_id;

  INSERT INTO lkCharge(charge_id, charge_datecreated, charge_name, charge_rate)
    VALUES(p_charge_id, UTC_DATE(), _name, p_new_charge_rate);

  SELECT LAST_INSERT_ID();
END//