如何存储旧数据,这是正确的方法吗?

时间:2019-05-22 13:16:16

标签: mysql sql database-design

问题:存储带有日期的起始价格。价格可以多次更改,并且还应存储更改价格的原因。

除了制作一张价格表,我想不出另一种方法了?

CREATE TABLE price (
    start_price decimal(4,2) NOT NULL,
    price_date timestamp,
    PRIMARY KEY (start_price, price_date)
);

CREATE TABLE pricechange (
    start_price decimal(4,2) NOT NULL,
    new_price decimal(4,2) NOT NULL,
    price_date date NOT NULL,
    reason varchar(100),
    FOREIGN KEY (start_price, price_date)
    REFERENCES price(start_price, price_date)
);

pricechange表中出现错误,我也不知道如何实际使用sql将价格中的价格存储到pricechange中,并将新价格存储为价格。

例如价格=100。newprice = 50原因:太贵了。应该是这样的:

价格表: current_price:50 price_date:价格创建的时间戳

价格变化: 起始价:100 new_price:50 日期:价格变动的时间戳 原因:太贵了

3 个答案:

答案 0 :(得分:0)

具有priceeffective_fromreason列的单个表怎么样?然后,您可以通过一点狡猾的方式使用视图显示current_prices

CREATE TABLE product_prices (
   product_id     int          NOT NULL
 , effective_date datetime     NOT NULL DEFAULT Current_Timestamp
 , price          decimal(4,2) NOT NULL
 , reason         varchar(400) NOT NULL
 , CONSTRAINT pk_product_prices PRIMARY KEY (product_id, effective_date)
 , CONSTRAINT fk_product_prices_products FOREIGN KEY (product_id) REFERENCES products (product_id)
);

CREATE VIEW current_product_prices
  AS
SELECT product_prices.product_id
     , product_prices.price
FROM   product_prices
 INNER
  JOIN (
        SELECT product_id
             , Max(effective_date) AS max_effectve_date
        FROM   product_prices
        WHERE  effective_date <= Current_Timestamp
        GROUP
            BY product_id
       ) AS current_price_date
    ON current_price_date.product_id = product_prices.product_id
   AND current_price_date.max_effectve_date = product_prices.effective_date
;

这是空代码(即概念性代码,未经测试),因为我不在可以立即运行MySQL的地方。

...但是应该是说明性的(足够)!

答案 1 :(得分:0)

从价格更改表开始,因为这是您真正需要的:

CREATE table foo (


id int,
attribute varchar(20),
value varchar(20)

)
INSERT into foo
VALUES
(1,'Name', 'Carl'),
(1,'Jobtitle', 'Driver'),
(2,'Name', 'Lisa'),
(2,'Age', '15'),
(3,'Name', 'Jon'),
(3,'Age', '43'),
(3,'Jobtitle  ', 'Programmer')

SELECT e.id, STUFF((SELECT  ', ' + attribute+'='+value
     FROM foo EE
     WHERE  EE.id=E.id

 FOR XML PATH('')), 1, 1, '') AS listStr

FROM foo E
GROUP BY E.id

您只需在此表中插入新价格即可。

然后,您可以使用触发器维护表create table price_changes ( price_change_id int auto_increment primary key, start_price decimal(4,2) NOT NULL, new_price decimal(4,2) NOT NULL, price_date date NOT NULL, reason varchar(100) ); 。或者,如果您愿意,可以查看:

current_prices

答案 2 :(得分:0)

我不同意其他答案(到目前为止)。我怀疑您的示例已经简化,并且/或者随着时间的推移会变得更加复杂。因此,查询将变得混乱和/或缓慢。

我建议2张桌子。可以将一个视为“当前”,将一个视为“历史”。每当价格发生变化时,history就会进入INSERTed,并且current会得到更新。我将借助TRIGGER在应用代码存储的Pro 中执行这两个步骤。

根据要应用于每个表的查询来设计每个表的列。在您发现FOREIGN KEYs的需求之前,请不要考虑它们。请记住,这两个表可能永远不会在同一查询中使用。