【发布时间】:2019-01-18 18:36:30
【问题描述】:
在进入架构和表之前,我想先分享一下我想要实现的目标。我正在开发一种快递应用程序,其中有一些categories,每个类别都有一个预定义的price。
但是,确定价格有点难看(缺乏对称性和图案;至少,我似乎找不到任何东西)。我举个例子:
考虑以下类别:文档、重型文档、笔记本电脑、纸箱、重型纸箱。
1) 文件: 适用于重量较轻的文件,重量在 0.5 公斤以下。价格是 20 美元,固定的。
[价格表中存储的价格:20.00]
例如一件 300 克的商品,价格为 20 美元。
2) 重型文件: 适用于超过 0.5 公斤的文件。与文档类别不同,它没有固定价格!相反,它有一个单价:每公斤 10 美元,这将适用于每公斤 0.5 公斤以外/之后的价格。
[价格表中存储的价格:10.00]
例如一件 2 公斤的商品,价格为 35 美元(1.5 克 = 15 美元 + 0.5 = 20 美元)
3) 笔记本电脑:简单明了,100 美元。没什么特别的,没有任何约束。
[价格表中存储的价格:100.00]
例如一件 2 公斤的商品,价格为 35 美元(1.5 克 = 15 美元 + 0.5 = 20 美元)
4) 纸箱:来了一个有趣的。到目前为止,只有一个依赖项:weight。但是这个有一个额外的依赖:dimension。这有点类似于 Document 类别。对于 3 立方英尺 (CF) 以下的纸箱,价格为每 CF 80 美元。 Document 和 Carton 类别之间的区别在于,Document 具有固定价格,而 Carton 具有单价。但是等等,还有更多。还有一个额外的限制:尺寸重量比。在这种情况下,它是7kg per CF。如果物品的重量超过该比例,每增加一公斤,将收取 5 美元。这太令人困惑了,我知道。一个例子可能会有所帮助:
[价格表中存储的价格:80.00]
例如适用于 80kg 和 2CF 的纸箱;价格为 490 美元。方法如下:
先计算常规费用:80$*2CF = 160$ 现在让我们计算它是否超过比率:因为,1 CF = 7kg,因此,2CF = 14kg。但是物品的重量是 80 公斤,所以它超过了比例(14 公斤)
由于超过了这个比例,对于所有额外的公斤(80-14 = 66 公斤),每公斤将花费 5 美元:66 * 5 = 330 美元。加上正常费用后:330$+160$ = 490$。
5) Heavy Carton:这个适用于尺寸大于3CF的纸箱。与纸箱的区别在于单价。重型纸箱每 CF 60 美元。
[价格表中存储的价格:60.00]
例如适用于 80kg 和 5CF 的纸箱;价格为 525 美元。方法如下:
先计算常规费用:60$*5CF = 300$ 现在让我们计算它是否超过 Ratio:因为,1 CF = 7kg,因此,5CF = 35kg。但是物品的重量是 80 公斤,所以它超过了比例(35 公斤)
由于超过了这个比例,对于所有额外的公斤(80-35 = 45 公斤),每公斤将花费 5 美元:45*5 = 225 美元。加上正常费用后:300$+225$ = 325$。
如果您读到这里,我想我已经让您相信业务结构确实很复杂。现在让我们看看我的categories 架构:
+-------------------------+---------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------------+---------------------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(191) | NO | | NULL | |
| created_at | timestamp | YES | | NULL | |
| updated_at | timestamp | YES | | NULL | |
| dim_dependency | tinyint(1) | NO | | NULL | |
| weight_dependency | tinyint(1) | NO | | NULL | |
| distance_dependency | tinyint(1) | NO | | NULL | |
| dim_weight_ratio | varchar(191) | YES | | NULL | |
| constraint_value | decimal(8,2) | YES | | NULL | |
| constraint_on | enum('weight','dim') | YES | | NULL | |
| size | enum('short','regular','large') | YES | | regular | |
| over_ratio_price_per_kg | decimal(8,2) | YES | | NULL | |
| deleted_at | timestamp | YES | | NULL | |
+-------------------------+---------------------------------+------+-----+---------+----------------+
还有prices表的schema(是多态表,希望有朝一日能创建subcategories表):
+----------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+---------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| amount | decimal(8,2) | NO | | NULL | |
| created_at | timestamp | YES | | NULL | |
| updated_at | timestamp | YES | | NULL | |
| priceable_type | varchar(191) | NO | MUL | NULL | |
| priceable_id | bigint(20) unsigned | NO | | NULL | |
| deleted_at | timestamp | YES | | NULL | |
+----------------+---------------------+------+-----+---------+----------------+
我如何改进这种结构以尽可能保持动态和连贯性?
【问题讨论】:
-
这里有不同的意见。问题是:是否可以使用 SQL DB 代替规则引擎? 有时可以,但它是最优的还是可取的?考虑使用规则引擎 - 或服务(纯代码) - 用于规则并使用 DB 仅用于记录谓词
User (USR) got price (PRI) for product (PRD) based on rule number (RNO).您可以在不同的系统中记录规则。
标签: mysql database-design relational-database