5

互联网上的大多数问题都集中在 Order、OrderItem 上。关于设计一个全面处理在线零售各个方面(订单、订单商品、退货、退款、换货)的数据库几乎没有问题。

我基本上只知道这个数据模型。

产品(ProductID、名称等)
订单(OrderID、日期、总成本等)
OrderItem(OrderID、ProductID、数量、单价等)

基于上述结构,我该如何管理退货、退款、换货?

我注意到,当我在超市退货/换货时,那里的工作人员会重新生成一张新发票。这是他们处理退货、退款、换货的方式吗?

4

4 回答 4

4
  • (F table.column) 表示指向 table.column 的外键
  • (P) 表示主键
  • (U) 表示唯一键

以下是一些表格和示例数据...

addresses
    id          unsigned int(P)
    line1       varchar(50)
    line2       varchar(50) // Allow NULL
    city_id     unsigned int(F cities.id)
    zip         varchar(6) // 5 digits for US and MX, 6 characters (X9X9X9) for CA
    zip4        char(4) // Allow NULL

+----+-----------------+-------+---------+--------+------+
| id | line1           | line2 | city_id | zip    | zip4 |
+----+-----------------+-------+---------+--------+------+
|  1 | 123 Main Street | Apt A |      17 | 92101  | 1234 |
|  2 | 345 East Street | NULL  |      25 | T1X0L3 | NULL |
| .. | ............... | ..... | ....... | ...... | .... |
+----+-----------------+-------+---------+--------+------+

cities
    id                  unsigned int(P)
    state_id            unsigned int(F states.id)
    name                varchar(50)
    ...

+----+----------+-----------+-----+
| id | state_id | name      | ... |
+----+----------+-----------+-----+
| .. | ........ | ......... | ... |
| 17 |      130 | San Diego | ... |
| .. | ........ | ......... | ... |
| 25 |       14 | Calgary   | ... |
| .. | ........ | ......... | ... |
+----+----------+-----------+-----+

ISO 3166-1

countries
    id              char(2)(P)
    iso3            char(3)(U)
    iso_num         char(3)(U)
    name            varchar(45)(U)

+----+------+---------+---------------+
| id | iso3 | iso_num | name          |
+----+------+---------+---------------+
| .. | .... | ....... | ............. |
| CA | CAN  | 124     | Canada        |
| .. | .... | ....... | ............. |
| MX | MEX  | 484     | Mexico        |
| .. | .... | ....... | ............. |
| US | USA  | 840     | United States |
| .. | .... | ....... | ............. |
+----+------+---------+---------------+

请参阅PHP 的 crypt() 函数以对密码进行哈希处理。

customers
    id              unsigned int(P)
    first_name      varchar(50)
    middle_name     varchar(50) // Allow NULL
    last_name       varchar(50)
    email           varchar(255)
    username        varchar(32)
    password        varbinary(255) // hashed
    ...

+----+------------+-------------+-----------+----------------------------+-----------+----------+-----+
| id | first_name | middle_name | last_name | email                      | username  | password | ... |
+----+------------+-------------+-----------+----------------------------+-----------+----------+-----+
|  1 | John       | Quincy      | Public    | jqp@privacy.com            | johnqball | xxxxxxxx | ... |
|  2 | Jane       | NULL        | Doe       | ladyinred@chrisdeburgh.com | janeykins | xxxxxxxx | ... |
| .. | .......... | ........... | ......... | .......................... | ......... | .......  | ... |
+----+------------+-------------+-----------+----------------------------+-----------+----------+-----+

customers_addresses
    id              unsigned int(P)
    customer_id     unsigned int(F customers.id)
    address_id      unsigned int(F addresses.id)

orders
    id                  unsigned int(P)
    customer_id         unsigned int(F customers.id)
    bill_address_id     unsigned int(F addresses.id)
    ship_address_id     unsigned int(F addresses.id)
    created             datetime
    shipped             datetime
    ...

+----+-------------+-----------------+-----------------+---------------------+---------------------+-----+
| id | customer_id | bill_address_id | ship_address_id | created             | shipped             | ... |
+----+-------------+-----------------+-----------------+---------------------+---------------------+-----+
|  1 | 1           | 1               | 1               | 2012-12-31 23:59:59 | 2013-01-01 00:00:00 | ... |
+----+-------------+-----------------+-----------------+---------------------+---------------------+-----+

orders_products
    id              unsigned int(P)
    order_id        unsigned int(F orders.id)
    product_id      unsigned int(F products.id)
    quantity        unsigned int
    unit_price      double
    ...

+----+----------+------------+----------+------------+-----+
| id | order_id | product_id | quantity | unit_price | ... |
+----+----------+------------+----------+------------+-----+
|  1 | 1        | 1          | 1        | 12.34      | ... |
|  2 | 1        | 2          | 13       | 1.78       | ... |
| .. | ........ | .......... | ........ | .......... | ... |
+----+----------+------------+----------+------------+-----+

products
    id                  unsigned int(P)
    name                varchar(50)
    price               double
    ...

+----+----------+-------+-----+
| id | name     | price | ... |
+----+----------+-------+-----+
|  1 | Widget 1 | 12.34 | ... |
|  2 | Widget 2 | 1.78  | ... |
| .. | ........ | ..... | ... |
+----+----------+-------+-----+

returns
    id                      unsigned int(P)
    order_product_id        unsigned int(F orders_products.id)
    quantity                unsigned int
    ...

+----+------------------+----------+-----+
| id | order_product_id | quantity | ... |
+----+------------------+----------+-----+
|  1 | 1                | 1        | ... |
| .. | ................ | ........ | ... |
+----+------------------+----------+-----+

ISO 3166-2

states
    id              unsigned int(P)
    country_id      char(2)(F countries.id)
    code            char(2) // AB, AL, NL, etc.
    name            varchar(50) // Alberta, Alabama, Nuevo Leon, etc.
    ...

+-----+------------+------+------------+-----+
| id  | country_id | code | name       | ... |
+-----+------------+------+------------+-----+
| ... | .......... | .... | .......... | ... |
|  14 | CA         | AB   | Alberta    | ... |
| ... | .......... | .... | .......... | ... |
|  72 | MX         | CH   | Chiapas    | ... |
| ... | .......... | .... | .......... | ... |
| 130 | US         | CA   | California | ... |
| ... | .......... | .... | .......... | ... |
+-----+------------+------+------------+-----+

退货、退款和换货都是真正的退货——客户正在退回产品。你如何处理它取决于你的业务规则......

于 2013-09-04T16:10:17.373 回答
2

你可以建立一个处理退货和换货的表格,比如

Returns (ID, OrderID, ExchangeID)

因此,如果客户退货,您将 OrderID 放入 Returns 就完成了 - 如果他们交换了某些东西,您将处理新订单,然后将退回的商品的 OrderID 放入 Returns.OrderID 字段,并将新的 OrderID 放入 Returns .ExchangeID 字段,这样你就知道哪个产品被换成了什么。这应该足够灵活,以允许无限的回报和交换。

显然还有更多的事情要做——只是我脑海中浮现出一个让球滚起来的念头……

于 2013-09-04T03:23:43.643 回答
0

冒着混淆事物的风险,您需要另一个概念,即订单项目的生命周期。现在,您隐含了订单商品的“付费”生命周期。每个项目实际上都有其他与之相关的生命周期,例如“已订购”(例如在网上商店)、“有货”、“已打包”、“已发货”、“已交付”等。

销售后,您有额外的生命周期状态。

最简单的方法是创建一个查找表,其中包含每个生命周期状态的条目,我们称之为 LifecycleStatus,并从 OrderItem 表中创建一个外键列。但是,这可能无法为您提供足够的信息,并且会丢失任何类型的历史记录。

下一步是向您的 OrderItem 表添加一个包含外键的 LifecycleInfo 表。它还将有一列指向 LifecycleStatus 表的外键。这个表(它是一个关系表,多对多)还应该有额外的列,通常这至少是一个日期和一个字符串来保存描述性的东西。

这两个实体允许单个 OrderItem 行具有多个状态,并使用一些有用的信息来跟踪该状态。

处理这些条目的逻辑通常非常简单,例如防止同一行出现多次退款。

希望有帮助。

于 2013-09-04T10:06:24.660 回答
0

我想我得到了这个简单的解决方案,但不确定它有什么问题。

您甚至不需要创建任何表格,只需执行以下 2 件简单的事情:

第一,只需将 1 个字段(orderItemStatus)添加到 OrderItem 表中。OrderItemStatus(1为正常,2为returnRefund,3为returnExchange)

2、将relatedOrderID添加到Order表中。

产品(ProductID、名称等)
订单(OrderID、RelatedOrderID、日期、总成本等)
OrderItem(OrderID、ProductID、OrderItemStatus、Quantity、UnitPrice 等)

当用户购买商品时,生成 Order 并为 RelatedOrderID 字段留空,OrderItemStatus 也设置为 1。

当用户想要退货退款时,在 OrderItem 中添加 1 行,其中 OrderID 是现有的并设置 OrderItemStatus=2

当用户想要退换货时,将 1 行添加到 OrderItem 中,其中 OrderID (1) 是现有行并设置 OrderItemStatus=3。但是这次我们将创建一个新订单,它的 RelatedOrderID= (1)。此外,这个新订单的 OrderItem 将具有与 (1) 中的 OrderItem 相同的数量和 ProductID,我们为这个新订单设置 OrderItemStatus=1。

我不确定这是否是最简单但满足所有要求的解决方案

于 2013-09-04T10:59:40.987 回答