在数据库中存储2个昏暗的考勤表?

时间:2009-10-03 12:42:02

标签: database

我们有一个基于Web的应用程序,由MySQL数据库支持。

我们编码的系统的一部分要求我们为一周中的每一天的用户会话存储出席(即是/否)。例如,我们需要存储星期一到星期五,然后是每天,早上,午餐,下午,晚间会议等等。所以基本上它是一个2维的阵列。

我想知道在数据库中存储这个最干净的方法是什么?

目前,处理此问题的人似乎倾向于将此存储为每天一个int,其中1代表出勤率,0代表不参加。我认为要做的意思是使用位掩码(例如13表示1101,所以每个会话除了下午)。他们只是出于某种奇怪的原因将其存储为0和1。

我认为将它存储为bools(bits / tinyints)列表可能更容易,例如monday_morning,monday_lunch,monday_afternoon等,因为它在语义上更“正确”(我认为?),它可能更容易扩展/维护,而且我似乎也是团队中唯一一个如何使用做位操作......哈哈。

我想的另一种方法就是为每个用户提供1:1的表格,例如,他们 参加的所有时间的列表。这种方法的效率如何? (不确定是什么类型的读/写模式,但我猜测读/修改的范围相当均匀)。

对此有哪些建议?或者有更好的方法来存储这些数据吗?

另外,作为附注,它可能是布尔值 - 我们怀疑我们需要存储的状态多于参加/不参加表格,如果我们这样做,我们准备重新处理架构。或者人们建议强烈推动比特?

干杯, 维克多

2 个答案:

答案 0 :(得分:1)

我会规范它并有三个表:users,sessions和sessions_attended。用户将包含有关用户的信息,会话将包含有关会话的信息,sessions_attended将是一个连接表,指示用户参加的会话。正确地索引表格,结果连接应该非常有效。

 select users.name, sessions.name
 from users u join sessions_attended a on u.user_id = a.user_id
      join sessions s on s.session_id = a.session_id
 where sessions.course = ...some course id...

答案 1 :(得分:0)

您的第二种方法(单个列)“更正确”,因为它不违反第一范式。位掩码方法可以,因为您在一个列中存储了多个值(您要存​​储多个会话的值)。

并且不要在内部存储bit。你不会看到任何存储减少,例如,tinyint(引擎不会为你分配一个位,它只会限制可接受的值)。你也可以使用tinyint给自己一些喘息的空间。

修改

正如Mark指出的那样,如果你有多个bit列,它可以将它们打包成一个字节,但担心数据是占用一个字节还是四个可能是一个过早的优化。最常规化的解决方案是建议的解决方案,其中您有一个单独的表,指示参与者参加的会话。如果您的会话确实是固定的,那么我可能会通过位掩码或完全规范化的解决方案为每个会话分别设置列。

  1. 位掩码对数据进行模糊处理,并且需要按位操作(显然)。这些可能会在查询语法中造成混淆,因为您正在多次使用单词orand。这种方法也无法编入索引,因此找到所有参加的人员,比如早上或早上和晚上的会议,每次都需要进行一次表扫描。

  2. 完全规范化的解决方案会使数据查询复杂化。虽然它将支持索引编制,但它需要为您要检查的每种会话类型进行完全加入。

  3. 每会话一列的方法似乎是最好的解决方案。您仍然只处理一行数据,但您也可以使用有意义的语法进行查询并利用索引。