繁体   English   中英

建模分层数据结构

[英]Modeling a hierarchical data structure

20120304-简化的问题

假设我们有实体R,D和E,并且此关系基数

  • R <n:m> D
  • D <1:n> E

该规范的映射很简单,但是我们还有另一个要求:

  • R <n:m> E

附带条件:如果E1与某些D1相关并且此D1与R1相关,则E1可能仅被“分配”给R1。

不幸的是,即使E2与D2相关,而D2与R2相关-E2也可能与R2不相关。

  • 我正在寻找关系数据库模型。
  • 一个模型,如果D从Ra分离并重新附加到另一个Rb, 则不需要多次更新 在这种情况下,D的所有E都需要与Ra分离并也连接到Rb。

20120305-解决方法?

一位朋友建议创建一个实体DxR,该实体通过元组(D,R)链接其D和R。 然后创建一个关系

  • DxR <n:m> E

嗯...

20120302-原始问题

系统由顶层区域(Z)组成 一个区域可以具有多个区域(R)

所谓的部门(D)可以分配给区域 仅当每个部门属于不同的区域时,一个部门才能被分配到多个区域。

最后, 雇员(E)属于一个部门,并且只有一个部门

仅当员工部门属于该地区时,员工才能被分配到该地区。

重要提示: 员工不必属于其部门所属的所有区域。

假定在以下图形中E1属于D1。 E1也应该属于R1,但​​不属于R2-尽管D1属于R1和R2:

-     Z            Z
-   __|___      ___|___
-   R1   R      R2    R
-    \_________/
-     D1         

问:请提出对以上规范进行建模的关系数据库的表结构?

从某种意义上说,这个问题非常具体,有些人可能会认为它过于本地化。 但是,有一个更普遍适用的想法可能对将来的其他人有用,因此问题不一定太具体。

这些业务规则中真正有趣的部分是这一部分:( 我的重点是补充)

仅当每个部门属于不同的区域时,一个部门才能被分配到多个区域

这是一个模式,它以声明方式捕获了几乎所有陈述的业务规则,而不必诉诸任何触发器。

create table ZONE
( ID int not null
, NAME varchar(50) not null
, constraint PK_ZONE primary key clustered (ID)
)

create table REGION
( ZONE_ID int not null
, REGION_ID int not null
, NAME varchar(50) not null
, constraint PK_REGION primary key clustered (ZONE_ID, REGION_ID)
, conttraint FK_REGION__ZONE foreign key (ZONE_ID) 
    references ZONE (ID)
)

create table DEPARTMENT
( ID int not null
, NAME varchar(50) not null
, constraint PK_DEPARTMENT primary key clustered (ID)
)

create table EMPLOYEE
( ID int not null
, NAME varchar(50) not null
, DEPT_ID int not null
, constraint PK_EMPLOYEE primary key clustered (ID)
, constraint FK_EMPLOYEE__DEPARTMENT foreign key (DEPT_ID) 
    references DEPARTMENT (ID)
)

上表很明显。 但是,有一个特别的问题: REGION表具有一个复合主键,其中包括FK到ZONE 这对于传播有关部门必须在区域内不同的约束很有用。

将部门分配到区域需要一个相交表:

create table DEPT_ASGT -- Department Assignment
( REGION_ID int not null
, DEPT_ID int not null
, ZONE_ID int not null
, constraint PK_DEPT_ASGT (REGION_ID, DEPT_ID)
, constraint FK_DEPT_ASGT__REGION foreign key (ZONE_ID, REGION_ID) 
    references REGION (ZONE_ID, ID)
, constraint FK_DEPT_ASGT__DEPARTMENT foreign key (DEPT_ID) 
    references DEPARTMENT (ID)
, constraint UN_DEPT_ASGT__ZONES unique nonclustered (ZONE_ID, DEPT_ID)
)

这个交集表是很正常的,因为它对它链接的每个表都有一个外键。 此交集表的特殊之处在于唯一性约束。 这就是强制执行以下规则的规定:部门不能位于同一区域内的两个不同区域中。

最后,我们需要将员工映射到部门和地区。 这需要另一个交集表:

create table EMP_ASGT -- Employee Assignment
( REGION_ID int not null
, DEPT_ID int not null
, EMPLOYEE_ID int not null
, constraint PK_EMP_ASGT (REGION_ID, DEPT_ID, EMPLOYEE_ID)
, constraint FK_EMP_ASGT__DEPT_ASGT (REGION_ID, DEPT_ID) 
    references DEPT_ASGT (REGION_ID, DEPT_ID)
, constraint FK_EMP_ASGT__EMPLOYEE (EMPLOYEE_ID) refernces EMPLOYEE (ID)
)

您将注意到EMPLOYEE表具有DEPARTMENT的外键-这将强制执行以下规则:每个员工只能属于一个部门。 EMP_ASGT表添加有关员工参与的区域的详细信息。由于员工可能未参与其部门分配到的每个区域,因此EMP_ASGT表将员工连接到他们所参与的那些区域。

这是需要触发器或其他一些过程逻辑的地方。 您需要确保EMPLOYEE.department_id与EMP_ASGT中的记录保持一致。 您可以通过将EMPLOYEE的PK设置为ID和DEPT_ID的组合,尝试将其推入声明性参照完整性,但这将迫使您决定是否要违反3NF或使员工部门更改为一个程序丑陋的混乱局面。 归根结底,只要稍加触发即可确保EMP_ASGT不反对EMPLOYEE.DEPT_ID,这将大大减少麻烦。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM