表版本控制(历史表)和订单表关系 [英] Tables versioning (historical tables) and Order tables relationship

查看:91
本文介绍了表版本控制(历史表)和订单表关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我在 products 表中添加一个新产品或更改数据,它将自动添加到 products_history 。这是通过触发器完成的。



当客户下订单时,不需要在 order_products table。



要从 order_products 表中获取产品名称和价格, products_history 表不是产品



注意:



查看以下表格和结果:

  mysql>选择*从产品; 
+ ---- + ------------ + ------- + ------------------- - +
| id |名称|价格| timestamp |
+ ---- + ------------ + ------- + ------------------- - +
| 1 |产品63 | 2.00 | 2011-10-08 18:55:53 |
| 2 |产品42 | 3.00 | 2011-10-08 18:55:44 |
+ ---- + ------------ + ------- + ------------------- - +

mysql>选择* from products_history;
+ ---- + ------------ + ------- + ------------------- - +
| id |名称|价格| timestamp |
+ ---- + ------------ + ------- + ------------------- - +
| 1 |产品23 | 2.00 | 2011-10-08 18:55:44 |
| 2 |产品42 | 3.00 | 2011-10-08 18:55:44 |
| 1 |产品63 | 2.00 | 2011-10-08 18:55:53 |
+ ---- + ------------ + ------- + ------------------- - +

订单表格

  mysql> select * from`order`; 
+ ---- + ------------- +
| id | total_price |
+ ---- + ------------- +
| 1 | 9999.00 |
+ ---- + ------------- +

mysql> select * from order_products;
+ ---- + ---------- + ------------ + ---------------- ----- +
| id | order_id | product_id | product_timestamp |
+ ---- + ---------- + ------------ + ---------------- ----- +
| 1 | 1 | 2 | 2011-10-08 18:55:44 |
| 2 | 1 | 1 | 2011-10-08 18:55:53 |
+ ---- + ---------- + ------------ + ---------------- ----- +

从订单表中获取产品名称和价格:

  SELECT order.total_price,products_history。 * FROM` order` 
LEFT JOIN order_products ON order_products.order_id = order.id
LEFT JOIN products_history ON products_history.id = order_products.product_id
AND products_history.timestamp = order_products.product_timestamp
WHERE order.id = 1

结果

  + ------------- + ------ + --------- --- + ------- + --------------------- + 
| total_price | id |名称|价格| timestamp |
+ ------------- + ------ + ------------ + ------- + --- ------------------ +
| 9999.00 | 2 |产品42 | 3.00 | 2011-10-08 18:55:44 |
| 9999.00 | 1 |产品63 | 2.00 | 2011-10-08 18:55:53 |
+ ------------- + ------ + ------------ + ------- + --- ------------------ +

工作正常。



这个设计有什么重大缺陷,或者我可以采取不同的方法?






关于Extras的第二个问题...产品可以有附加功能或没有附加功能。我需要为 extra_group 表进行版本化吗?我只有版本为额外表。



请参阅下列表格:

  mysql> select * from extra_group; 
+ ---- + ------------------ +
| id |名称|
+ ---- + ------------------ +
| 1 |附加组一|
+ ---- + ------------------ +

mysql>选择* from extras;
+ ---- + --------- + ------- + --------------------- +
| id |名称|价格| timestamp |
+ ---- + --------- + ------- + --------------------- +
| 1 |额外1 | 0.30 | 2011-10-08 18:57:55 |
| 2 |额外2 | 2.31 | 2011-10-08 18:58:10 |
+ ---- + --------- + ------- + --------------------- +

mysql> select * from extras_history;
+ ---- + --------- + ------- + --------------------- +
| id |名称|价格| timestamp |
+ ---- + --------- + ------- + --------------------- +
| 1 |额外1 | 0.30 | 2011-10-08 18:57:55 |
| 2 |额外2 | 2.30 | 2011-10-08 18:57:55 |
| 2 |额外2 | 2.31 | 2011-10-08 18:58:10 |
+ ---- + --------- + ------- + --------------------- +


mysql>选择* from products_extras;
+ ---- + ------------ + ---------------- +
| id | product_id | extra_group_id |
+ ---- + ------------ + ---------------- +
| 1 | 2 | 1 |
+ ---- + ------------ + ---------------- +
//这意味着产品ID 2有extra_group_id = 1的附加功能

附加功能的订单表: p>

  mysql> select * from order_products_extras; 
+ ------------------- + ---------- + -------------- ------- +
| order_products_id | extra_id | extra_timestamp |
+ ------------------- + ---------- + -------------- ------- +
| 1 | 1 | 2011-10-08 18:57:55 |
| 1 | 2 | 2011-10-08 18:58:10 |
+ ------------------- + ---------- + -------------- ------- +

//客户从product_id 1中选择extra_id 1和2

使用类似上述的查询,从 extras_history 表中获得额外的名称和价格



触发器

  CREATE TRIGGER`extras-afterinsert` `extras` 
每个ROW BEGIN
INSERT INTO`extras_history` VALUES(NEW.`id`,NEW.`name`,NEW.`price`,NEW.`timestamp`);
END
|
CREATE TRIGGER`extras-afterupdate`在`extras`上更新后
用于每个ROW BEGIN
INSERT INTO`extras_history` VALUES(NEW.`id`,NEW.`name`,NEW。 `price`,NEW.`timestamp`);
END

products_history table。



使用历史表浪费时间,我只需要将名称/价格重复到 order_products order_products_extras 表?



注意:procuss和extras表中将有超过100,000行1000订单一天。

解决方案

我真的不明白你试图用历史表达到什么。如果产品价格快速变化,并且您想要保存当前时间的产品基本价格,为什么不将其放入order_product?

 订单:
order_id / created_at / status(PK:order_id)

order_products:
order_id / product_id / quantity / product_price(PK:order_id,product_id)

这样你不必每次都加入product_history。



PS:尽量不要在表/列名中使用保留字,比如order,它可以引入错误。


If I add a new product in the products table or change the data - it will automatically add into products_history. This is done by trigger.

When customer placed the order, there is no need to duplicate the name of product in the order_products table.

To get the pruduct name and price from the order_products table - you will query from the products_history table not the products table

Note: I am showing simple tables for demonstration.

See the following tables and the result:

mysql> select * from products;
+----+------------+-------+---------------------+
| id | name       | price | timestamp           |
+----+------------+-------+---------------------+
|  1 | Product 63 |  2.00 | 2011-10-08 18:55:53 |
|  2 | Product 42 |  3.00 | 2011-10-08 18:55:44 |
+----+------------+-------+---------------------+

mysql> select * from products_history;
+----+------------+-------+---------------------+
| id | name       | price | timestamp           |
+----+------------+-------+---------------------+
|  1 | Product 23 |  2.00 | 2011-10-08 18:55:44 |
|  2 | Product 42 |  3.00 | 2011-10-08 18:55:44 |
|  1 | Product 63 |  2.00 | 2011-10-08 18:55:53 |
+----+------------+-------+---------------------+

The orders tables:

mysql> select * from `order`;
+----+-------------+
| id | total_price |
+----+-------------+
|  1 |     9999.00 |
+----+-------------+

mysql> select * from order_products;
+----+----------+------------+---------------------+
| id | order_id | product_id | product_timestamp   |
+----+----------+------------+---------------------+
|  1 |        1 |          2 | 2011-10-08 18:55:44 |
|  2 |        1 |          1 | 2011-10-08 18:55:53 |
+----+----------+------------+---------------------+

To get the product name and prices from the orders table:

SELECT order.total_price, products_history. * FROM  `order` 
   LEFT JOIN order_products ON order_products.order_id = order.id
   LEFT JOIN products_history ON products_history.id = order_products.product_id
             AND products_history.timestamp = order_products.product_timestamp
WHERE order.id =1 

Result:

+-------------+------+------------+-------+---------------------+
| total_price | id   | name       | price | timestamp           |
+-------------+------+------------+-------+---------------------+
|     9999.00 |    2 | Product 42 |  3.00 | 2011-10-08 18:55:44 |
|     9999.00 |    1 | Product 63 |  2.00 | 2011-10-08 18:55:53 |
+-------------+------+------------+-------+---------------------+

It seem to work fine.

Is there any major flaw in this design or what I could have done differently?


Second question about Extras... A product can have extras or without extras. Do I need to versioned for extra_group table? I have only versioned for the extra table.

See the following tables:

mysql> select * from extra_group;
+----+------------------+
| id | name             |
+----+------------------+
|  1 | Extras Group One |
+----+------------------+

mysql> select * from extras;
+----+---------+-------+---------------------+
| id | name    | price | timestamp           |
+----+---------+-------+---------------------+
|  1 | Extra 1 |  0.30 | 2011-10-08 18:57:55 |
|  2 | Extra 2 |  2.31 | 2011-10-08 18:58:10 |
+----+---------+-------+---------------------+

mysql> select * from extras_history;
+----+---------+-------+---------------------+
| id | name    | price | timestamp           |
+----+---------+-------+---------------------+
|  1 | Extra 1 |  0.30 | 2011-10-08 18:57:55 |
|  2 | Extra 2 |  2.30 | 2011-10-08 18:57:55 |
|  2 | Extra 2 |  2.31 | 2011-10-08 18:58:10 |
+----+---------+-------+---------------------+


mysql> select * from products_extras;
+----+------------+----------------+
| id | product_id | extra_group_id |
+----+------------+----------------+
|  1 |          2 |              1 |
+----+------------+----------------+
//This mean Product ID 2 have extras from  extra_group_id = 1

Order table for extras:

mysql> select * from order_products_extras;
+-------------------+----------+---------------------+
| order_products_id | extra_id | extra_timestamp     |
+-------------------+----------+---------------------+
|                 1 |        1 | 2011-10-08 18:57:55 |
|                 1 |        2 | 2011-10-08 18:58:10 |
+-------------------+----------+---------------------+

//Customer selected extra_id 1 and 2 from product_id 1

Use similar query like above to get the extra name and price from the extras_history table

Triggers:

CREATE TRIGGER `extras-afterinsert` AFTER INSERT ON `extras`
FOR EACH ROW BEGIN
    INSERT INTO `extras_history` VALUES (NEW.`id`, NEW.`name`, NEW.`price`, NEW.`timestamp`);
END
|
CREATE TRIGGER `extras-afterupdate` AFTER UPDATE ON `extras`
FOR EACH ROW BEGIN
    INSERT INTO `extras_history` VALUES (NEW.`id`, NEW.`name`, NEW.`price`, NEW.`timestamp`);
END

And similar for the products_history table.

Am I wasting my time using historical tables, should I just duplicate names/prices into order_products and order_products_extras tables ?

Note: There will be over 100,000 rows in the procucts and extras tables.. and over 1000 orders a day.

解决方案

I really couldn't understand what you are trying to achieve with history tables. If the products price changes rapidly and you want to save the products base price at that current time why not put it into order_product ?

orders :
order_id / created_at / status (PK : order_id)

order_products : 
order_id / product_id / quantity /  product_price (PK : order_id, product_id)

this way you wouldn't have to join product_history every single time. you can do same denormalization for extras aswell.

P.S : try not to use reserved words like "order" in table / column names, it can introduce bugs.

这篇关于表版本控制(历史表)和订单表关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆