自定义字段数据库设计用于会员申请

时间:2012-07-14 16:22:34

标签: sql database-design

我需要为会员申请设计数据库,需要为多个组织定制分类

以下是数据集:

  • 组织类型1: 姓名,电子邮件,加入年份,结束年份,角色,位置。

  • 组织类型2: 姓名,电子邮件,加入年份,结束年份,角色,部门,子组织,位置

  • 组织类型3: 姓名,电子邮件,加入年份,结束年份,角色,身份证号码

为它设计数据库的最佳方法是什么? 少数字段项是常见的,很少是特定于组织,组织类型是有限的

选项1:

  • members_table - member_id,name,email,joining_year,end_year,role
  • members_org_type_1 - member_id,location
  • members_org_type_2 - member_id,department,sub_org,location
  • members_org_type_3 - member_id,id_no

选项:2

  • members_table - member_id,name,email,joining_year,end_year,role
  • member_fields - member_id,field_type,field_value
  • field_labels - field_type,field_label

第二种类型看起来很有希望,但不知道如何做联接操作member_table& member_fields包含必填字段?

2 个答案:

答案 0 :(得分:4)

这是数据库设计中的常见问题,有3种最常见的处理方法(如果我们计算EAV,则有4种方法):

  1. 三个单独的表,每种类型一个。

  2. 一个表 - 包含很多列 - 其中一些表将被允许具有Null。数据库不能轻易处理完整性(哪些列组合将为空,哪些不是),并且通常由应用程序处理。这是@noa的答案,它会导致代码略少,并且可能更容易找到一个有效的(尽管不是完美的)应用程序。

  3. 一个Member表(这是超类型)和另外3个表,每个子类型一个。这允许您没有Null并强制使用哪些列,具体取决于组织类型。 (这是你的选择1)

    您还可以在所有表​​格中添加org_type列。这意味着一个 UNIQUE上的其他Member (org_type, member_ID)约束和FOREIGN KEY约束(来自每个子类型表)已更改为包含此org_type列。像这样:

    CREATE TABLE Member
    ( MemberID 
    , Org_Type
    , Name
    , ...
    , Role
    , PRIMARY KEY (MemberID)
    , UNIQUE KEY (Org_Type, MemberID)
    , CHECK Org_Type IN (1, 2, 3)
    ) ;
    
    CREATE TABLE Member_Type_1
    ( MemberID 
    , Org_Type
    , Location
    , PRIMARY KEY (MemberID)
    , FOREIGN KEY (Org_Type, MemberID)
        REFERENCES Member(Org_Type, MemberID) 
    , CHECK Org_Type = 1
    ) ;
    

    最后有(你的选择2)EAV:

  4. 根据维基百科的说法,
  5. Entity-Attribute-Value模型是:

      

    用于描述实体的数据模型,其中可用于描述它们的属性(属性,参数)的数量可能很大,但实际应用于给定实体的数量相对适中。在数学中,这个模型被称为稀疏矩阵。 EAV也称为对象 - 属性 - 值模型,垂直数据库模型和开放模式。

    有很多理由不在关系数据库中使用EAV,主要是因为有关数据类型和参照完整性的问题(不能轻易实施),甚至编写简单查询的困难(最终用大量连接编写)和效率。请参阅DBA.SE问题的Simon Righarts的答案:Is there a name for this database structure?

    在某些情况下,有一些理由认为它是一个有效的选择,正如Aaron Bertrand的文章所解释的那样:What is so bad about EAV, anyway?,特别是当你有很多专栏时甚至更多的事情你事先并不知道什么您需要的列(由客户定制)。如果您希望组织能够添加自定义列,则可能是您的情况。

    但请注意,构建高效的EAV模型/应用程序并不容易。您实际上是在数据库中构建RDBMS。

答案 1 :(得分:2)

如果组织类型有限并且很少更改,只需使用一个表:

  • members_table - member_id,name,email,joining_year,end_year,role,location,department,sub_org,id_no

在与组织类型无关的字段中使用空值,并在显示信息时隐藏不适用的字段。

我给出了类似的答案here,尽管它是针对不同的数据库。