教授数据库设计的好例子

7
有没有好的场景可以用来教授关系型数据库和SQL?我能找到的所有例子都要么太简单,要么有不可能的域限制(比如全名唯一)。特别是我正在尝试为规范化找到一些好的例子:那些不立即适合3NF和BCNF的表。目前,我为每个级别使用不同的问题。
当然,我也很想要一些糟糕设计的数据库的好例子,但在掌握基本原理之前会有些分散注意力。
谢谢,一些不错的例子。我将学生/班级的标记为答案,因为我认为这是迄今为止最好的,但如果有人想贡献更多,请随时提供。
9个回答

9

我记得学生/班级似乎是一个经典的例子,你可以在里面加入成绩,使它变得更加复杂。

  • 学生可以参加多个课程

  • 课程可以有多个学生

  • 对于学生参加的每一门课程,他们都可以有一个成绩

最初你可以在一张表中完成这个任务,然后再将其规范化为三张表。


可以进一步为班级设置学年/学期。 - Russ Cam
不要忘记教职工。还有章节(课程概念的计划版本)。 - Robert C. Barth
很好,通过每年限制考试/课程数量,我可以获得一些有趣的依赖关系。 - Mark

6

离题

作为一名教授数据库课程的人,我建议在掌握基本查询技能之前先忘记设计。只有当学生们了解如何从数据库中获取数据后,他们才更好地理解规范化的必要性。如果你从规范化和设计开始讲解,你会失去大部分学生的兴趣。设计应该是数据库课程的最后一个模块,但我看过的所有教材都是从设计开始的。

更好的方法是在学习查询时同时查询好的和坏的数据库设计,这样当到了讲解设计的时候,他们真正理解坏设计带来的痛苦。


我完全同意 - 你需要确定限制是什么,以及是什么推动你达到更高水平的设计。 (+1) - Mark

2
电子商务/购物车设计很好,因为大多数人都能理解这个概念,并且您可以将其推向许多不同的方向。您可以做简单的事情,如购物车、购物车商品、用户、订单、订单商品等。然后您可以深入研究用户地址、用户电子邮件、商品、商品详情、商品历史记录等。这可能会引发很多良好的辩论,因为有很多判断。

谢谢,我也喜欢这个,或许可以作为最后一个问题。 - Mark
最好的部分是,您可以展示一些数据库设计问题,例如当您不存储订单详细信息而依赖于与产品表的连接时会发生什么情况,而该表中的价格每季度更新。您还可以使用此功能来展示滥用级联删除的危险性。哎呀,删除客户也从财务报告中删除了订单。 - HLGEM

1
我永远不会忘记的一个概念是关于命名中“复数”与“单数”的问题。很久以前我的一位优秀导师曾告诉我,应该将表名设计为复数形式,列名则应该是单数形式,并且永远不要为列名创建特定于时间的名称。时间名称的例子包括NutsSold1998、NutsSold1999、NutsSold2000等。永远不要在列名中添加年份、月份、周数或时间等内容。
表名示例: Employees(而不是Employee) Parts(而不是Part) Students(Student)
列名示例: EmployeeID(而不是EmployeesID或EmployeeIDS等) PartID(而不是PartsID或PartIDS等) StudentID(而不是StudentsID或StudentIDS等)
此外,要注意ID、Code、Key、Number等的正确使用... 我们总是被教导不要在列名中使用“Key”,除非它是实际的表键(主键或外键,但不一定是备用键)。大多数情况下,在列名后添加“ID”会比添加“Number”或“Code”更好,但这取决于上下文。

这需要时间和经验来设计表格,阅读好的材料,例如书籍Database Design For Mere MortalsData Modeling for Everyone。此外,花费大量时间查看好的设计并分析它们。这绝对是一门手艺,只有通过时间和实践才能变得更好。


1

另一个好的模型是发票项目模型,因为“最佳选择”取决于各种因素:

  • 读写操作的数量;
  • 性能;
  • 是否需要报告功能?

查看此数据模型:

发票

  • ID
  • 日期

发票项目

  • 发票ID
  • 描述
  • 金额

应用程序功能包括:

  • 创建新发票;
  • 每晚创建并发送两个报告:(a) 每张发票的总金额,(b) 当天总金额。

假设您每天平均有5个项目的发票和100张发票,您每天需要执行以下操作:

  • 在InvoiceItem上进行5 x 100次写操作;
  • 在Invoice上进行100次写操作;
  • 从Invoice和InvoiceItem中进行5 x 100 + 100 = 600次读取操作(报告(a));
  • 从Invoice和InvoiceItem中进行5 x 100 + 100 = 600次读取操作(报告(b))。

所以总共是=每天1800次操作,假设读取和写入的成本相同。

如果在实体"Invoice"上添加"TotalAmount"属性,则情况有些不同:

  • 在"InvoiceItem"上进行5次100次写入;
  • 在Invoice(包括TotalAmount)上进行100次写入;
  • 仅从Invoice(报告(a))中获得100个;
  • 仅从Invoice(报告(b))中获得100个;

总共800次操作:)


1
这里有一个示例,它可以追溯到我自己上大学的日子 - 它既是数据库设计挑战,也是面向对象设计挑战。
并非所有信息都一次性公开 - 挑战的一部分是看如何调整设计以处理新要求,以及正确的规范化如何使这更容易。
假设您必须为大学/学院情况设计数据库,并想处理注册。
您拥有所教授的课程。每门课程都有一个标题和每周的常规时间安排。
每门课程都有一个讲师来呈现课程。
每门课程都有许多学生来学习课程。
每门课程都有一个或多个导师来帮助学生学习。您不需要跟踪哪些导师帮助哪些学生。
一些课程有多个常规时间安排。
一些课程有多个讲师。
讲师和导师都会受到报酬,这意味着我们需要为税务目的跟踪一些信息。税务部门不关心他们为什么付款 - 他们希望我们对每个人只有一条记录。

在一些课程中,讲师也会兼任导师的角色,以便更近距离地观察学生如何掌握材料。

有些导师也是其他课程的讲师。

要成为某门课程的导师,你必须曾经是该课程的学生。

并非每个学生都会因通过课程而获得学分——有些人只是旁听课程,不需要学分。

未通过课程的学生可以在以后再次参加该课程。我们需要记录每次尝试的情况。


0

还有一个图书馆的例子(一个图书馆有很多书,每本书都有作者和出版商,可以将它们分别推入不同的表中进行规范化)。


0

回复:

我尤其想找一些好的规范化示例: 那些不符合3NF和BCNF的表。

您可以在此处找到规范化数据库模式样本:http://www.microsoft.com/sqlserver/2005/en/us/express-starter-schemas.aspx。您可以从头开始构建它们,向您的学生展示“规范化的方法”。特别是看看联系人管理模式。您可以轻松地使模式去规范化并将其恢复为3NF或更高级别。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接