Database design 一张有很多职责的桌子的最佳方法

Database design 一张有很多职责的桌子的最佳方法,database-design,Database Design,我目前正在制作各种申请表格的电子版。每个表单很可能需要一些关于用户的特定数据。为了便于讨论,这里有一个简化的版本 Form Required Info ¯¯¯¯¯¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ Mileage Claim Does user have a lease car? Ove

我目前正在制作各种申请表格的电子版。每个表单很可能需要一些关于用户的特定数据。为了便于讨论,这里有一个简化的版本

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的表?

将其全部放入users表是一种不断增长的“模式”。最终,您将拥有一个包含300个字段的表—名字、姓氏、地址、工作地址、夏季地址、ownsaleasecar,如Espizza等等

我希望他们都共享一个用户对象。用户将反映他们的共同点。如果他们使用不同类型的用户(例如,有些人拥有个人信息,有些人拥有完全不同的数据集,比如说,雇员),那么拥有用户和雇员,或者一些这样的人可能是合理的。主要的一点是,我不会试图把不同的类型塞进同一张表中

编辑- 另外一点是,将不同的数据类型组合在一起会使执行完整性变得不可能——假设将“RentalCarUser”和“EmployeeUser”分组到同一个表中,并且为RentalCarUser设置了字段“DoesUserHaveLeaseCar”。那么,它将是null,或者对员工有一个无意义的默认值,如果您真的想要强制每个租车用户都必须拥有该信息,那么您不能在数据库级别(field!=null)强制执行它,因为您有其他用户不适用该值。为员工添加一个触发器来填写“NA”是没有帮助的,因为这样你就有了一大堆带有“NA”的记录,你很难判断这是正确的还是缺少数据。

你有3个表

现在你有了超复杂的逻辑


现在是不是整个事情都是由一个巨大的开关声明驱动的。但通过这样做,您可以使用户可以填写哪些表单的逻辑变得极其复杂:

  • 用户不能有空电话号码
  • 用户必须拥有有效的汽车租赁(这可能很难确定)
  • 用户必须在20到50岁之间,有一个活跃的电子邮件,并住在蒙大拿州,除非他超过60岁,住在佛罗里达州

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

我将使用用户名以模块化方式设计数据库(如果强制执行唯一性)或者用户ID作为引用所有相关信息的键。通过将信息模块化到多个表中,您会做得更好,并学到更多知识。

您似乎不熟悉数据库规范化,因此我建议您阅读一些关于数据库规范化的教程。这里只有一个例子:

您希望从要求您在数据库中建模的纸质表单开始。表单上的每个字段都将成为(未规范化)数据库中的一个字段。由于您要处理多个表单,因此可能会有一些相同的字段。这是一个很好的线索,您应该将它们抽象到一个单独的表中。例如,听起来这三个表单都有一个位置供员工填写姓名,以确定填写表单的人,因此您需要一个员工表


从这里开始,只需遵循互联网上众多规范化教程中的一个。第三范式是大多数人所能达到的,但即使是第二范式也是改进。您可能经常会发现您的设计已经处于第一个标准形式。

但是这样做会使逻辑变得极其复杂吗?这是一种反模式吗?不,该注释指的是用户可能填写或不填写的表单:业务逻辑。我把它更新得很清楚(呃)。
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;
}