简体   繁体   English

建模分层数据结构

[英]Modeling a hierarchical data structure

20120304 - Streamlined question 20120304-简化的问题

Suppose we have entities R, D and E and this relational cardinalities 假设我们有实体R,D和E,并且此关系基数

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

The mapping of this specification is straight forward, but we have another requirement: 该规范的映射很简单,但是我们还有另一个要求:

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

Side condition: E1 might only get 'assigned' to an R1, if E1 is related to some D1 and this D1 is related to the R1. 附带条件:如果E1与某些D1相关并且此D1与R1相关,则E1可能仅被“分配”给R1。

Unfortunately, even if E2 is related to a D2, which is related to an R2 - E2 might not be related to R2. 不幸的是,即使E2与D2相关,而D2与R2相关-E2也可能与R2不相关。

  • I'm in search of a relational DB model. 我正在寻找关系数据库模型。
  • A model, which doesn't require multiple updates if a D gets detached from an Ra and reattached to another Rb. 一个模型,如果D从Ra分离并重新附加到另一个Rb, 则不需要多次更新 In this case, all Es of D need to get detached from Ra and attached to Rb too. 在这种情况下,D的所有E都需要与Ra分离并也连接到Rb。

20120305 - Workaround? 20120305-解决方法?

A friend propose to create an entity DxR which links its D and its R by means of a tuple (D,R). 一位朋友建议创建一个实体DxR,该实体通过元组(D,R)链接其D和R。 Then create a relation 然后创建一个关系

  • DxR < n:m > E DxR <n:m> E

Hm... 嗯...

20120302 - Original question 20120302-原始问题

System is composed of top level zones (Z) . 系统由顶层区域(Z)组成 A zone may have several regions (R) . 一个区域可以具有多个区域(R)

So called departments (D) may be assigned to regions . 所谓的部门(D)可以分配给区域 One department may get assigned to more than one region, only if each region belongs to a different zone. 仅当每个部门属于不同的区域时,一个部门才能被分配到多个区域。

Finally, employees (E) belong to one and only one department . 最后, 雇员(E)属于一个部门,并且只有一个部门

Employees may get assigned to a region only if, employee's department belongs to the region. 仅当员工部门属于该地区时,员工才能被分配到该地区。

Important: An employee need not belong to all regions its department belongs to. 重要提示: 员工不必属于其部门所属的所有区域。

Assume, that in the following graphics E1 belongs to D1. 假定在以下图形中E1属于D1。 E1 should also belong to R1, but not belong to R2 - although D1 belongs to R1 and R2: E1也应该属于R1,但​​不属于R2-尽管D1属于R1和R2:

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

Q: Please propose the relations DB's table structure which models the above specification? 问:请提出对以上规范进行建模的关系数据库的表结构?

This question is very specific in one sense and some people might argue that it is too localized. 从某种意义上说,这个问题非常具体,有些人可能会认为它过于本地化。 There is, however, one more generally applicable idea that might be useful to other people in the future, so it isn't necessarily true that the question is too specific. 但是,有一个更普遍适用的想法可能对将来的其他人有用,因此问题不一定太具体。

The really interesting part of these business rules is this one: (my emphasis added) 这些业务规则中真正有趣的部分是这一部分:( 我的重点是补充)

One department may get assigned to more than one region, only if each region belongs to a different zone . 仅当每个部门属于不同的区域时,一个部门才能被分配到多个区域

Here is a schema that captures almost all of the stated business rules declaratively without having to resort to any triggers. 这是一个模式,它以声明方式捕获了几乎所有陈述的业务规则,而不必诉诸任何触发器。

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)
)

The above tables are pretty obvious. 上表很明显。 However, there is one particular quirk: The REGION table has a compound primary key that includes the FK to ZONE . 但是,有一个特别的问题: REGION表具有一个复合主键,其中包括FK到ZONE This is useful for propagating the constraint about departments having to be distinct within a zone. 这对于传播有关部门必须在区域内不同的约束很有用。

Assigninging departments to regions requires an intersection table: 将部门分配到区域需要一个相交表:

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)
)

This intersection table is pretty normal insofar as it has a foreign key to each of the tables that it links. 这个交集表是很正常的,因为它对它链接的每个表都有一个外键。 What is special about this intersection table is the unique constraint. 此交集表的特殊之处在于唯一性约束。 This is what enforces the rule that a department can't be in two different regions within the same zone. 这就是强制执行以下规则的规定:部门不能位于同一区域内的两个不同区域中。

Lastly, we need to map employees into departments and into regions. 最后,我们需要将员工映射到部门和地区。 This requires another intersection table: 这需要另一个交集表:

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)
)

You will note that the EMPLOYEE table has a foreign key to DEPARTMENT - That enforces the rule that each employee can belong to only one department. 您将注意到EMPLOYEE表具有DEPARTMENT的外键-这将强制执行以下规则:每个员工只能属于一个部门。 The EMP_ASGT table adds the details about which regions the employee participates in. Since an employee may not be involved in every region that his or her department is assigned to, the EMP_ASGT table connects employees to just those regions where they have some involvement. EMP_ASGT表添加有关员工参与的区域的详细信息。由于员工可能未参与其部门分配到的每个区域,因此EMP_ASGT表将员工连接到他们所参与的那些区域。

Here is the one place where a trigger or some other procedural logic is needed. 这是需要触发器或其他一些过程逻辑的地方。 You need to make sure that EMPLOYEE.department_id stays consistent with the records in EMP_ASGT. 您需要确保EMPLOYEE.department_id与EMP_ASGT中的记录保持一致。 You could try to push this into the declarative referential integrity by making the PK of EMPLOYEE a compound of ID and DEPT_ID, but that would force you to decide whether you want to violate 3NF or make your employee department changes a procedurally ugly mess. 您可以通过将EMPLOYEE的PK设置为ID和DEPT_ID的组合,尝试将其推入声明性参照完整性,但这将迫使您决定是否要违反3NF或使员工部门更改为一个程序丑陋的混乱局面。 At the end of the day, a little trigger to make sure that EMP_ASGT doesn't disagree with EMPLOYEE.DEPT_ID would be much less trouble. 归根结底,只要稍加触发即可确保EMP_ASGT不反对EMPLOYEE.DEPT_ID,这将大大减少麻烦。

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

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