具有大量职责的表的最佳方法

时间:2009-02-19 18:09:08

标签: database-design

我目前正致力于创建各种请求表单的电子版。每个表单很可能需要一些关于用户的特定数据。为了论证,这是一个简化版本。

      Form                                 Required Info
 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯              ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯             
 Mileage Claim               Does user have a lease car?
 Overtime Claim              Contract type (permanent/temp). Salary
 Procurement Request         User role (supervisor, technician)

我目前不知道总共会有多少表格会出现在这个系统上,或者他们可能需要的其他额外信息。但可以肯定的是,他们都需要标准的东西,如姓名,电子邮件,工资单号等。

你会采取什么方法来模拟这个?将它全部放入users表中或创建大量引用User?

的表

4 个答案:

答案 0 :(得分:1)

将所有内容全部投入到用户表中是一种不断增长的“Ball of Mud”模式的配方。最终你会有一个包含300个字段的表 - 名字,姓氏,地址,工作地址,夏天地址,ownsaleasecar,likespizza,....

我让他们共享一个用户对象。用户将反映他们共同拥有的东西。如果他们使用不同类型的用户(例如,某些人拥有个人信息,而某些用户拥有完全不同的数据集),那么拥有用户和员工或其他类似用户可能是合理的。重点是我不会尝试将不同类型的东西挂在同一张桌子上。

编辑 - 另外一点是,将不同的数据类型组合在一起会使执行完整性变得不可能 - 假设您将“RentalCarUser”和“EmployeeUser”分组到同一个表中,并且您具有RentalCarUsers的字段“DoesUserHaveLeaseCar”。那么,它将为null或者对于Employees具有无意义的默认值,并且如果您实际上想要强制每个租车用户必须具有该信息,则不能在数据库级别强制执行它(字段!= null)因为您有其他用户,该值不适用。添加触发器以填写员工的“NA”没有帮助,因为您已经获得了大量带有“NA”的记录,并且您无法轻易判断该数据是正确还是缺失。

答案 1 :(得分:0)

你得到了3张桌子。

users_tbl
---------
id
name
...


form_tbl
--------
id
name
...


formRequirement_tbl
-------------------
form_requirement_id
form_id
and/or Flag

现在你得到了超级复杂的逻辑。

bool CheckRequirements($formid, $userid)
{
    $arrayOfFormRequirementIds = goGetFormRequirementIds($formid);
    $result = false;
    foreach($requirementId,$andOrFlag in $arrayOfFormRequirementIds)
    {
       switch($requirementId)
       {
          case 1:
               $sql = "Select 1 from leases where userid = $userid and active = 1";
               $result |= executeSQLQueryScalar($sql);
               if($andOrFlag == AND && !$result) 
                    return false;
               break;
          ...
        }
     }
  return $result;
}

现在是整个事情被一个巨大的转换声明驱逐了吗? 即可。但通过这样做,您可以制定用户填写极其复杂的表单的逻辑:

  • 用户不能拥有空电话号码
  • 用户必须拥有有效的汽车租赁(可能很难理解)
  • 用户必须年龄在20至50岁之间,有活跃的电子邮件,并且住在蒙大拿州,除非他年满60岁并住在佛罗里达州

如果您只是存储列名以检查空值,那么您将无法执行复杂的逻辑。如果您在用户表中存储单个位,如“canFillOutMarriageForm”,则必须等到更新这些位的作业运行后才能填写weddingForm。

答案 2 :(得分:0)

我会使用用户名(如果强制执行唯一性)或用户ID作为引用所有相关信息的密钥以模块化方式设计数据库。您可以更好地完成这项工作,并将信息模块化为多个表格。

答案 3 :(得分:0)

您似乎不熟悉数据库规范化,因此我建议您阅读一些相关教程。这只是一个例子: http://dev.mysql.com/tech-resources/articles/intro-to-normalization.html

您要开始的地方是您要求在数据库中建模的纸质表单。表单上的每个字段都成为(非标准化)数据库中的字段。由于您正在处理多个表单,因此您可能会有一些共同的字段。这是一个很好的线索,您应该将它们抽象到一个单独的表中。例如,听起来所有三种表单都有一个地方让员工写出他们的名字来识别谁填写表格,所以你需要一张员工表。

从那里,只需按照互联网上的众多规范化教程之一进行操作即可。第三种正常形式是大多数人去的,但即使是第二种正常形式也是改进。您可能经常发现您的设计已经处于初始状态。