Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database 在数据库中存储二维考勤表?_Database - Fatal编程技术网

Database 在数据库中存储二维考勤表?

Database 在数据库中存储二维考勤表?,database,Database,我们有一个基于web的应用程序,由MySQL数据库支持 我们正在编码的系统的一部分要求我们在一周中的每一天存储用户会话的出席情况(即是/否)。例如,我们需要存储从周一到周五的数据,然后存储每天、上午、午餐、下午、晚上的会话等,所以本质上它是一个2维数组 我想知道在数据库中存储这些信息的最干净的方法是什么 目前,处理此问题的人员似乎倾向于将其存储为每天一个int,1表示出席,0表示不出席。我认为这样做的意思是使用位掩码(例如,1101使用13,所以除了下午之外,每个会话都使用13)。出于某种奇怪的

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

我们正在编码的系统的一部分要求我们在一周中的每一天存储用户会话的出席情况(即是/否)。例如,我们需要存储从周一到周五的数据,然后存储每天、上午、午餐、下午、晚上的会话等,所以本质上它是一个2维数组

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

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

我想它可能更容易存储为bool(bit/tinyint)列表,例如周一早上、周一午餐、周一下午等等,因为它的语义更“正确”(我想?),它可能更容易扩展/维护,而且我似乎也是团队中唯一一个对如何进行bit操作有任何了解的人……哈哈

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

对此有什么建议?还是有更好的方法来存储这些数据

另外,作为旁注,它可能是布尔型的——我们可能需要在表中存储比出席/不出席更多的状态,如果我们这样做了,我们准备重新处理模式。还是有人建议强烈追求整数而不是比特

干杯, Victor

您的第二种方法(各个列)更“正确”,因为它不违反第一个标准形式。位掩码方法确实如此,因为在单个列中存储多个值(为多个会话存储值)

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

编辑

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

  • 位掩码使数据模糊,需要按位操作(显然)。这些在查询语法中可能会令人困惑,因为您正在多次使用单词
    。这种方法也无法编制索引,因此要找到所有参加(比如)上午或上午和晚上会议的参与者,每次都需要扫描表格

  • 完全规范化的解决方案将使数据查询复杂化。虽然它将支持索引,但它需要为您要检查的每个会话类型进行完全联接


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

    我将对其进行规范化,并有三个表:用户、会话和会话。用户将包含有关用户的信息,会话将包含有关会话的信息,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...
    

    Sybase(因此我怀疑MS SQL Server)在一个字节中存储了多达8位的列,因此您确实获得了存储好处Sheya,是的,据我所知,很多RDBMS无论如何都会将连续的位打包在一起。如果是这样的话,Tinyint仍然是一条路要走吗?但我不是一个真正的DB人。你会推荐使用位掩码方法吗?我在数据库中使用它们的经验较少——如果代码适合我需要运行的读/写类型,我会使用它,所以从这一方面来说,我想它在这里会很有用——但是,它真的在数据库中做了很多事情吗?或者其他方法(如tvanfosson上述建议)是否更正确/有效,更普遍?干杯,维克多海亚,唯一的问题是,实际上,用户更可能参加所有的会议,或者比这里和那里更长的连续时间。基本上,这就像一个为期五天的会议,大多数人都会参加五天的会议,或者迟到一天,或者提前半天离开。我们真的只需要对出席人数存储是/否。您是否仍然建议我们使用联接表方法?谢谢,维克多,我的感觉是你会正常化,直到正常化成为一个问题。