我正在存储来自多家餐厅的所有订单。(不是链式店)这些餐厅有独特的商品,这些商品可能属于也可能不属于同一类别(甜的、咸的、饮料、主菜、开胃菜等),然后可以还有子类别(甜->冻糕、薄饼;饮料->热、冷、酒精等)
对于每个订单,可能有多个项目,其中包含定制内容(删除或添加),以及不属于定制内容的特殊注释。将数据序列化为 json 字符串将是一个简单的选择,但搜索和组织这些有值(value)的数据确实很困难。
每个项目都由与其类别中的其他项目共同或不共同的部分组成。该元素具有适合每种可能组合的零件。所有默认部分都可以选择退出。
让我们从一个例子开始。类别、子类别、常用选项、项目名称、独特项目选项。并非所有级别都会一直使用。
餐厅A
- 甜甜的
- 冰淇淋
- # 勺(如果 > 1,则可以有多种口味)
- Vanilla
- 巧克力
- 芒果
- 冷冻酸奶
- 变体 1
- a(默认)
- b(默认)
- c
- d
- e
- 变体 2
- 一个
- b(默认)
- c
- d(默认)
- e
- 变体 3
- a(默认)
- b(默认)
- c
- d
- e(默认)
- 变体 1
- 冰淇淋
- 咸味
- 披萨
- 夏威夷菜
- 菠萝(默认)
- 奶酪(默认)
- 火腿(默认)
- 番茄酱(默认)
- 培根
- 蘑菇
- 意大利辣香肠
- 创建您自己的
- 菠萝
- 奶酪
- 火腿
- 番茄酱
- 培根
- 蘑菇
- 意大利辣香肠
- 夏威夷菜
- 披萨
- 饮料
- 热门
- 咖啡
- 拿铁咖啡
- 卡布奇诺
- 茶
- 冷
- 可乐
- 瓶装水
- 冰咖啡/茶变化
- 热门
B餐厅
- 甜甜的
- 项目 x
- 第 y 项
- 项目 z
- 咸味
- 项目
- 项目q
- 项目 r
C餐厅
- 项目o
- 项目p
- 项目g
- 项目站点
如果我去餐厅 a,点了两勺 Vanilla 和巧克力、2 份冷冻酸奶变体 1、1 份不含 b 的冷冻酸奶变体 2,以及一份夏威夷蘑菇披萨,我将如何存储该订单?或者使用 sql 是错误的想法,我应该使用文档存储(nosql)系统?理想情况下,我不想将(默认)部件存储为自定义的一部分;只有不同的东西才有趣。
最佳答案
学习信息建模和关系模型。
为您的应用程序提供一个简单的信息模型是最好的开始。 (实际上,对于任何编程问题。)您可能实际上应该使用关系 DBMS。
您需要了解信息建模 (IM)。还有关系模型 (RM) 和(某种)关系数据库管理系统 (RDBMS)。 IM 在使用 RM 的地方变得精确。请参阅this回答。尤其是它的第一个链接。另请参阅我对建模问题的回答。
RM 允许通用的无循环/声明式(逻辑符号)查询和操作,并具有自动实现和某些优化的某些性能。仅应出于对特定查询和性能的工程权衡而使用任何其他数据结构或语言。 每个计算任务都是如此。 (任何程序的精确规范都可以用逻辑符号来编写。)
你现在可以停下来了。但RM的思维方式如下。
查找应用程序关系语句。
基本思想是找到描述应用程序情况的语句。
I go to restaurant a, and order
a double scoop of vanilla and chocolate,
2 frozen yogurt variation 1, 1 frozen yogurt variation 2 with no b, and
a hawaiian pizza with mushrooms
制作填空版本。
person [p] at restaurant [r] has some pending order o
AND o includes item some item i
AND item i is an ice cream
AND item i has [n] scoops of flavour [f]
...
AND order o includes some item j
AND item j is a pizza
AND item j base is hawaiian
AND item j has extra [mushrooms]
查找基本陈述。
person [p] at restaurant [r] has pending order [o]
order [o] includes item an item i
item [i] is an ice cream
item has [n] scoops of flavour [f]
...
item [j] is a pizza
item [i] has base [b]
base [b] has topping [t]
item [i] has extra topping [t]
item [i] has topping [t]
基表有一个语句。
每个基本语句都有一个基表。基表声明看起来像是其语句的简写,反之亦然。
order(p,r,o) -- person [p] at restaurant [r] has pending order [o]
base(b,t) -- base [b] has topping [t]
topping(i,t) -- item [i] has topping [t]
基表保存使其成立的行。比如下面的情况
person No_name at restaurant a placed order 12345
AND person philipxy at restaurant a placed order 22222
AND person philipxy at restaurant b placed order 33333
AND for all other (p,r,o) NOT order(p,r,o)
基表
order(p,r,o) -- person [p] at restaurant [r] has pending order [o]
具有表格值
+----------------------+
| p | r | o |
+======================+
| No_name | a | 12345 |
+----------------------+
| philipxy | a | 22222 |
+----------------------+
| philipxy | b | 33333 |
+----------------------+
找到最佳基本语句和表格的 RM 方法是标准化(至 5NF)。
每个表都有一个声明
由其他语句组成的每个语句都有一个表。每个表都保存使其陈述成立的行。语句由逻辑运算符组合而成,表由相应的表运算符组合/计算。
例如行位于
there's some restaurant r, order o and item i where:
person [p] at restaurant [r] has pending order [o]
AND order [o] includes item [i]
AND item [i] has [n] scoops of flavour [f]
AND [p]=No_name AND [r]=a
或使用简写行,其中
EXISTS r,o,i: order(p,r,o) AND item(o,i) AND cone(i,n,f) AND p=No_name AND r=a
即行
SELECT p,n,f
FROM order JOIN item JOIN cone
WHERE order.o=item.o AND item.i=cone.i
AND order.p=No_name AND r=a
+--------------------------+
| p | n | f |
+==========================+
| No_name | 1 | vanilla |
+--------------------------+
| No_name | 1 | chocolate |
+--------------------------+
从陈述开始。即应用程序关系。即关系。因此关系模型。
唉。
可能您得到的所有建模建议都会谈论“an”“m:n”“association”[应用程序关系],而不询问是哪个。即哪个语句。 (请注意,他们会以非常规的非 RM 方式使用“关系”。)
实体关系建模 (ERM) 和对象关系映射/建模 (ORM) 误解了 RM。他们把上面的事情搞混了。但你可以将上面的内容转化为他们的概念。
关于多家餐厅的sql数据库设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24282046/