【发布时间】:2010-09-23 17:27:15
【问题描述】:
我们正在为学校编写记录管理产品,其中一项要求是能够管理课程安排。我还没有查看我们如何处理这个问题的代码(我目前在另一个项目中),但是我开始想知道如何最好地处理这个要求的一个特定部分,即如何处理这样一个事实每门课程可以在一周中的一天或多天举行,以及如何最好地将这些信息存储在数据库中。为了提供一些上下文,一个简单的Course 表可能包含以下列:
Course Example Data
------ ------------
DeptPrefix ;MATH, ENG, CS, ...
Number ;101, 300, 450, ...
Title ;Algebra, Shakespeare, Advanced Data Structures, ...
Description ;...
DaysOfWeek ;Monday, Tuesday-Thursday, ...
StartTime
EndTime
我想知道的是,在这个(人为的)示例中处理 DaysOfWeek 列的最佳方法是什么?我遇到的问题是它是一个多值字段:也就是说,您可以在一周中的任何一天上一门课程,而同一门课程可以在一天以上的时间内上完。我知道某些数据库本身就支持多值列,但是假设数据库本身不支持它,是否有“最佳实践”来处理这个问题?
到目前为止,我已经提出了以下可能的解决方案,但我想知道是否有人有更好的解决方案:
可能的解决方案 #1:将 DaysOfWeek 视为位字段
这是我脑海中闪现的第一件事(我不确定这是否是一件好事……)。在此解决方案中,DaysOfWeek 将被定义为一个字节,前 7 位将用于表示星期几(每天一位)。 1 位表示课程在一周中的相应日期举行。
优点:易于实现(应用程序可以处理位操作),适用于任何数据库。
缺点:更难编写使用DaysOfWeek 列的查询(尽管您可以在应用程序级别处理此问题,或在数据库中创建视图和存储过程以简化此操作),中断关系数据库模型。
可能的解决方案 #2:将 DaysOfWeek 存储为字符串
这与使用位字段本质上是相同的方法,但不是处理原始位,而是为一周中的每一天分配一个唯一的字母,DaysOfWeek 列只存储一个字母序列,指示星期几一个课程正在举行。例如,您可以将每个工作日与一个单字符代码相关联,如下所示:
Weekday Letter
------- ------
Sunday S
Monday M
Tuesday T
Wednesday W
Thursday R
Friday F
Saturday U
在这种情况下,周一、周二和周五举行的课程将具有 'MTF' 的值 DaysOfWeek,而仅在周三举行的课程将具有 DaysOfWeek 的值 'W'。
优点:在查询中更容易处理(即,您可以使用INSTR 或其等效项来确定某个课程是否在给定日期举行)。适用于任何支持 INSTR 或等效函数的数据库(我猜是大多数......)。使用DaysOfWeek 列的查询也更易于查看,并且一目了然。
缺点:唯一真正的“缺点”是,与位域方法一样,它通过在单个字段中存储可变数量的值来破坏关系模型。
可能的解决方案 #3:使用查找表(丑陋)
另一种可能性是创建一个新表来存储一周中所有日期的唯一组合,并将Course.DaysOfWeek 列简单地作为该查找表的外键。然而,这个解决方案似乎是最不优雅的一个,我之所以考虑它,是因为它看起来像是 The Relational WayTM 做事。
优点:从关系数据库的角度来看,这是唯一“纯”的解决方案。
缺点:不优雅且笨重。例如,您将如何设计用户界面以根据查找表将相应的工作日分配给给定的课程?我怀疑用户想要处理“周日”、“周日、周一”、“周日、周一、周二”、“周日、周一、周二、周三”等这样的选择......
其他想法?
那么,有没有更优雅的方式来处理单列中的多个值?还是建议的解决方案之一就足够了?对于它的价值,我认为我的第二个解决方案可能是我在此处概述的三种可能解决方案中最好的,但我很想知道是否有人有不同的意见(或者确实是完全不同的方法)。
【问题讨论】:
-
我在回复中留下了一些关于域的警告。看看吧。
标签: sql database-design