如何在数据库中存储已付款和未付款的订单?
How to store paid and unpaid orders in database?
我正在设计一个数据库,我需要在其中存储客户的已付款订单和未付款订单。 两类订单与其他 table 具有 相同的属性和关系。
我想出了两个设计:
1.将两类订单分开 tables:优点: 这种设计帮助我快速区分购物车中的订单和那些这是有偿的。每当客户重新访问我的网站时,我只需要查找该特定客户的 UnpaidOrder table,我的购物车就准备好了。
缺点: 每当为 UnpaidOrder table 中的订单付款时,我需要移动相应的行(UnpaidOrder 和其他 table s 与它链接)到 PaidOrder table 及其相应的 tables。此设计还需要 2 倍数量的 table:例如。 UnpaidOrderDeliveryAddress, UnpaidOrderCreditCard, ... 用于与 UnpaidOrder 和 PaidOrderDeliveryAddress, PaidOrderCreditCard, ... 用于 PaidOrder 的关系。
2。两个类别的通用 table 和一个额外的 Status 属性:优点: 我不需要在支付未付款的订单。另外,对应关系的table个数减半
缺点: 我为每一行存储了一个额外的 Status 属性。每当客户重新访问我的网站时,我需要查找订单 table 并且我需要检查该特定客户每一行的状态属性 (paid/unpaid)。因此,购物车将需要更长的时间来加载。
我的问题是:
- 考虑到用户众多且应用程序繁重,哪种设计在性能方面更好?
- 对于我的要求有什么好的替代品吗?
如果您担心性能,一个可能的建议是您可以执行类似于版本 2 的操作,但是当一个项目被标记为 "paid" 时,使用触发器 运行 一个单独的查询(对于例如,您可以将付费指示器保留为 NULL,直到它被支付)然后当它被填充时,将它移动到一个单独的 table,就像在版本 1.
中一样
换句话说,所有项目都将在 table 1 中,直到它们被支付,当它们被自动移动到 table 2,然后从 table 1 中删除。
CREATE TRIGGER trigger_name
AFTER UPDATE
ON `UnpaidOrder`.`paid` FOR EACH ROW
BEGIN
DECLARE vOrder varchar(50);
SELECT order_number() INTO vOrder;
INSERT INTO PaidOrder
//code here from the first table
DELETE from `UnpaidOrder` //if you choose to do so, or you could leave it on the table; up to you
//criteria that you wish to delete
END;
另一个意见....
不需要额外的规范化表(UnpaidOrderDeliveryAddress、UnpaidOrderCreditCard、...用于与 UnpaidOrder 和 PaidOrderDeliveryAddress 的关系、PaidOrderCreditCard、...用于 PaidOrder)。如果你认为 FOREIGN KEYs
需要这样,我会反对在这种情况下使用 FOREIGN KEYs
。简单的索引就足够了。
由于您最终拥有的 "paid" 个条目将远远多于 "unpaid" 个条目,而付费条目本质上是 'history' 您很少需要触摸的条目,因此我倾向于 2 个表。
我可能不会使用触发器 -- 我宁愿在我有更多控制权的应用程序代码中使用它。
您是否希望每秒执行超过 100 SQL 个语句?如果不是,我不会叫它"heavy"。
一定要小心地将适当的语句组用 BEGIN..COMMIT
括起来。此外,在导致更新的 SELECT 上使用 FOR UPDATE
。
我正在设计一个数据库,我需要在其中存储客户的已付款订单和未付款订单。 两类订单与其他 table 具有 相同的属性和关系。
我想出了两个设计:
1.将两类订单分开 tables:
缺点: 每当为 UnpaidOrder table 中的订单付款时,我需要移动相应的行(UnpaidOrder 和其他 table s 与它链接)到 PaidOrder table 及其相应的 tables。此设计还需要 2 倍数量的 table:例如。 UnpaidOrderDeliveryAddress, UnpaidOrderCreditCard, ... 用于与 UnpaidOrder 和 PaidOrderDeliveryAddress, PaidOrderCreditCard, ... 用于 PaidOrder 的关系。
2。两个类别的通用 table 和一个额外的 Status 属性:
缺点: 我为每一行存储了一个额外的 Status 属性。每当客户重新访问我的网站时,我需要查找订单 table 并且我需要检查该特定客户每一行的状态属性 (paid/unpaid)。因此,购物车将需要更长的时间来加载。
我的问题是:
- 考虑到用户众多且应用程序繁重,哪种设计在性能方面更好?
- 对于我的要求有什么好的替代品吗?
如果您担心性能,一个可能的建议是您可以执行类似于版本 2 的操作,但是当一个项目被标记为 "paid" 时,使用触发器 运行 一个单独的查询(对于例如,您可以将付费指示器保留为 NULL,直到它被支付)然后当它被填充时,将它移动到一个单独的 table,就像在版本 1.
中一样换句话说,所有项目都将在 table 1 中,直到它们被支付,当它们被自动移动到 table 2,然后从 table 1 中删除。
CREATE TRIGGER trigger_name
AFTER UPDATE
ON `UnpaidOrder`.`paid` FOR EACH ROW
BEGIN
DECLARE vOrder varchar(50);
SELECT order_number() INTO vOrder;
INSERT INTO PaidOrder
//code here from the first table
DELETE from `UnpaidOrder` //if you choose to do so, or you could leave it on the table; up to you
//criteria that you wish to delete
END;
另一个意见....
不需要额外的规范化表(UnpaidOrderDeliveryAddress、UnpaidOrderCreditCard、...用于与 UnpaidOrder 和 PaidOrderDeliveryAddress 的关系、PaidOrderCreditCard、...用于 PaidOrder)。如果你认为 FOREIGN KEYs
需要这样,我会反对在这种情况下使用 FOREIGN KEYs
。简单的索引就足够了。
由于您最终拥有的 "paid" 个条目将远远多于 "unpaid" 个条目,而付费条目本质上是 'history' 您很少需要触摸的条目,因此我倾向于 2 个表。
我可能不会使用触发器 -- 我宁愿在我有更多控制权的应用程序代码中使用它。
您是否希望每秒执行超过 100 SQL 个语句?如果不是,我不会叫它"heavy"。
一定要小心地将适当的语句组用 BEGIN..COMMIT
括起来。此外,在导致更新的 SELECT 上使用 FOR UPDATE
。