自定义电子商务 Web 应用程序中的关系数据库问题

Relational database trouble in a custom e-commerce web application

首先,对于您即将阅读的英语不好,我深表歉意...

我正在尝试开发一个小型电子商务 Web 应用程序(从头开始 - 不使用 Magento、OpenCart、Shopify 等平台...),用于在我居住的城市送披萨。餐厅还出售一些意大利食品,如意大利面、鱼和肉。

我被关系数据库问题困住了,我将解释我在数据库中做了什么。我将编写表结构,然后是一些示例记录。

与意大利面不同,披萨的价格根据大小(属性)而变化。

数据将以如下方式展示(请看下图):

在前端显示 披萨 示例记录。当用户选择尺码时,价格将显示在下方,并且还会显示两个用于添加或减去该产品(具有该尺码)数量的控件。

这是一个具有一个属性的披萨(一个 属性 影响 价格),因为有些属性不会影响价格,即:烹饪或熟度。另一种情况是,一个产品具有多个影响价格的属性。

总结:

  1. 没有属性的产品,只有一个价格。
  2. 只有一个属性影响价格的产品。
  3. 具有影响价格的两个或更多属性的产品。

MySQL 表格:

Categories(ID, name):
1, Pizzas
2, Pastas

_

Products(ID, category_id, name, description)
1, 1, Margherita, Lorem ipsum
2, 1, 4 Stagioni, Lorem ipsum
3, 1, Capricciosa, Lorem ipsum
4, 2, Bologna, Lorem ipsum
5, 2, Pesto, Lorem ipsum

_

Attributes (ID, name)
1, Size
2, Cooking

_

Meta_attributes(ID, attribute_id, name)
1, 1, Small
2, 1, Medium
3, 1, Big
4, 2, Blue
5, 2, Medium well
6, 2, Well done
7, 2, Overcooked

_

meta_attributes_values(ID, product_id, meta_attrib_id, value)
1, 1, 1, 12
2, 1, 2, 16
3, 1, 3, 19
4, 2, 1, 14
5, 2, 2, 18
6, 2, 3, 20

_

在此架构中,当且仅当产品具有 meta_atrib 时,产品才具有价值,并且为了具有 meta_atrib,它必须具有属性。但是意大利面是"linear"它没有任何属性,一种意大利面产品只有一个价格。

问题:

  1. 数据库应该如何处理所有这些情况?
  2. 一个属性影响另一个属性的特殊情况呢?例如,假设比萨饼的价格根据其大小而变化(这是正确的),但假设它还有一个名为 "extra" 的属性,并且额外属性的价格根据比萨饼的大小而变化披萨,因为变大需要更多。我知道这个例子不是很清楚,但我希望我已经清楚地表达了自己的意思。

感谢阅读!

请务必注意,您描述的模式并不代表实际订单,它代表披萨的抽象概念。产品、属性、元属性和值的图表比逐项订单需要的要复杂得多。

订单中到底有什么?有产品,每个产品都有一个底价;正如您所注意到的,有些东西 会影响产品的价格 。这些修饰符至少有两种类型:

  • Additive 修饰符将固定金额附加到基本价格上。 "medium" 比萨比底价高 4 美元; "large" 多花 7 美元。
  • Dependent 修饰符在通过附加修饰符调整后更改基础价格。依赖修饰符的最简单形式是乘数:无论披萨的调整价格是多少,带有 "extra hot peppers" 的比萨的价格要高出 0.10 倍。

运气好的话,这就是您要处理的全部。如果 "extra peppers" 在小号上花费 0.50 美元,在中号上花费 0.60 美元,在大号上花费 1.00 美元,那么您必须跟踪所有这三者并与尺寸修饰符相关联,因为添加不是调整后价格的一致函数。在这种情况下,单独处理尺寸等附加修饰符——例如,通过在产品中设置基本价格、中等价格和大价格——可能更有效。

仍然可以通过相同地处理产品和属性并将它们存储在单个 table 中并使用自身的外键来表示父子关系来实现更简单的表示。实际上,您没有产品,只有属性。 "Margherita" 将是一个属性,将 12 美元添加到 0 美元的商品基本价格中。

但回到具体的,如果您也需要使用 Order_Items 跟踪订单,即使每个属性一行的解决方案也很笨拙,因为每个订单项中都有大量外键订单的。在这种情况下,最好将您的子项目(或所有内容,如果您将其全部合并为一个 table)存储在 JSON 字段中,这样您的 Order_Items table 看起来像这样:

id order_id subtotal attributes
1  1        17.60       [{"name": "Margherita", "adds": 12.00}, {"name": "Medium", "adds": 4}, {"name": "Extra hot peppers", "multiplier": 0.10}]
2  1        12.00       [{"name": "Pesto", "adds": 12.00}]

这是 a) 非规范化和 b) 破坏参照完整性。在这种情况下,这两者都是好事!如果您曾经调整过价格,甚至从菜单上拿过一些东西,您肯定不想搞砸您的簿记或遇到外键约束错误。