为食谱设计关系数据库
不编程的时候,我就喜欢做饭。我喜欢翻阅烹饪书籍,寻找新奇有趣的食谱。翻阅了不少烹饪书籍后,我开始注意到食谱属性显示的类型存在某种规律。我觉得根据烹饪书籍的食谱设计一个关系数据库或许是个不错的练习。
背景
那么,关系数据库是由什么构成的呢?关系!在关系数据库中,一切都是相互关联的。由于万物互联,我们可以创建一个包含数百种属性类型的大表,但我们并没有这样做。为什么呢?数据完整性!数据完整性是指数据的整体完整性、准确性和一致性。为了确保数据库的数据完整性,它需要具备这三个特性。
- 无重复值
- 无错误值
- 表之间没有断开的关系
那么,我们如何实现这一点呢?我们将数据拆分成多个易于管理且唯一的表。然后,我们通过关系连接这些表。说到关系,我们只能使用三种类型(实际上只有两种,但我们稍后会讲到)。这些类型是:
- 一对一 - (例如:一个人有一本护照,一本护照对应一个人)
- 一对多(例如:一个人可以有多张信用卡,但多张信用卡只能属于一个人)
- 多对多(例如:许多班级有许多学生,而许多学生有许多班级)
最后一条看起来很难读懂,对吧?的确如此。而且它根本行不通。它行不通的原因与一个叫做“父子”关系的概念有关。让我们看看“一对多”的例子,试着找出谁是父级,谁是子级。在人和信用卡中,哪个离不开另一个?信用卡!世界上不存在无限量的神奇信用卡,而且它们都分配给了某个人。所以,在这个场景中,父级是人,信用卡是子级。现在让我们看看“多对多”关系。那里的父级和子级分别是谁?在一种情况下,学生如果不上课就不能成为学生。在另一种情况下,如果没有学生,班级真的就是班级吗?这就是多对多关系行不通的原因。我们没有明确的父级。
我们通过将“多对多”关系拆分为两个“一对多”关系来解决这个问题。这样我们就有了明确的父级和子级。因此,如果我们要对学生表和班级表进行建模,我们会得到类似这样的结果。
其中“学生班级”表是学生表和班级表的子表。
数据库设计
好了,有了这些知识,我们来构建一个食谱数据库吧!我们先来看一个食谱,并提取相关信息。
Recipe Title: Simple Cheese Pizza
Recipe Description: A great pizza that's really easy to make.
Recipe Ingredients:
2.5 cups All Purpose Flour
1 Packet Yeast
1.5 teaspoons Sugar
0.75 teaspoons salt
2 tablespoons Olive Oil
0.75 cups warm water
1.25 cups cheese
1 cup tomato sauce
这些信息似乎足够我们开始使用了。看看上面的食谱,哪些数据真正依赖于单个食谱?我认为是“食谱标题”和“食谱描述”,所以我们把它们放到一个表格里。
好的,现在我们来看看配料部分。首先,我们知道一个食谱有很多配料,但一种配料也有很多食谱。我可以在另一个食谱中使用 2.5 杯面粉,所以没有必要在我的数据库中重复这个值。我们也可以说,我可以在数据库中使用 2.5 杯其他配料,比如 2.5 杯红糖。那么,是否有必要在数据库中不断重复 2.5 杯呢?我认为没有必要。
让我们从单一食材开始,并将其扩展到食谱中的所有食材。查看食材时,我们会注意到一些关键特征:计量数量、计量单位和配料。下图以“1 杯番茄酱”为例。
1 = measurement qty
cup = measurement unit
tomato sauce = ingredient
然后我们可以根据这三个特征创建三个表。
好的,我们已经将所有信息都表示出来了,但是如何将食谱表与三个配料表连接起来呢?我们使用连接表!
这个数据库能让我们做什么呢?好吧,我们来看看两个披萨食谱。
Recipe Title: Simple Cheese Pizza
Recipe Description: A great pizza that's really easy to make.
Recipe Ingredients:
2.5 cups All Purpose Flour
1 Packet Walmart Yeast
1.5 teaspoons Sugar
0.75 teaspoons salt
2 tablespoons Olive Oil
0.75 cups warm water
1.25 cups cheese
1 cup tomato sauce
Recipe Title: Simple Cheese Pizza with Pepperoni
Recipe Description: A great pizza with pepperoni that really easy to make.
Recipe Ingredients:
2.5 cups All Purpose Flour
1 Packet Walmart Yeast
1.5 teaspoons Sugar
0.75 teaspoons salt
2 tablespoons Olive Oil
0.75 cups warm water
1.25 cups cheese
1 cup tomato sauce
1 bag pepperoni
我们知道食谱的标题和描述是不同的,因此我们需要存储这两个值。但看看配料表。除了最后的“1 袋意大利辣香肠”之外,其他都没什么变化。我们真的需要复制所有这些值吗?如果这样做会怎么样?让我们看看“1 包沃尔玛酵母”。如果沃尔玛倒闭了,沃尔玛酵母很可能就不复存在了。所以,我们必须找到这种酵母的替代品,然后更改的记录不止一条,而是两条。这看起来并不难,但现在想象一下,我们有 10,000 个使用沃尔玛酵母的食谱。那可就太多了。有了上面的数据库,我们只需要更改一个表值,而不是 10,000 个!谢谢关系!
结论
数据库设计没有唯一的正确答案,但有很多错误答案。数据库设计既是艺术,也是科学。它需要深入了解所有试图连接的数据之间的关系。我发现,如果我没有投入足够的时间进行正确的数据库设计,我的应用程序就会变得缺乏灵活性和效率。一开始,这个概念对我来说很难理解,尤其是多对多关系的建模。我很想知道您对数据库设计的看法,以及它是否值得花费大量时间。请告诉我!
文章来源:https://dev.to/amckean12/designing-a-relational-database-for-a-cookbook-4nj6