我有一个旧的数据库设计,我认为我可以简化并使其更加规范化。我希望对此有所了解。以下是数据库的“规则”:
该组织由三个层次结构组成:
一个。局 - 是最高级别的 湾办公室 - 每个局都可以有很多办事处 C。分部 - 每个办公室可以有许多部门
我们的员工可以在三个层级中工作。例如:
一个。我们有局级人员。他们不属于办公室或部门。监督所有办公室,但不属于他们 湾我们有办公室级员工,不属于特定部门,但监督所有部门 C。属于分部的分部级人员
我们也有项目。一个项目可以处于不同的层次:
一个。局宽的项目
湾跨越多个办事处的项目
C。项目只是在一个部门
每个项目都需要由至少一名员工管理,具有特定角色(项目经理),员工表将由具有其他角色的个人,甚至多个角色组成。
目前,我有以下架构(为简洁起见,它是简略的):
使用此架构,我发现了以下问题:
在此模型中,所有项目都与分部绑定。但实际上,并非所有项目都直接归因于分工。有些可能在办公室或局级。其他人可能跨越多个办事处或办事处(但不能跨越多个局和办事处)。所以,我通过在每个组织层中提供额外选项来解决这个问题。例如。在分部表中,我可以选择Office Wide或Bureau Wide。或者我可能有像Office One / Office Two这样的选项。
我看到的另一个问题是:每个角色表都有许多重复的值。例如,如果我们看一下divisionRole表。几乎所有部门都有相同的作用。所以,我有DivisionManager,divisonPM,divisionLead多次列出(每个分区一次)。有时候,一个部门可能有一个独特的位置,但这种情况很少见。对于BureauRole和OfficeRole表
因此,我正在寻找有关如何更好地规范化此数据库以及解决上述方案的建议。有人有建议吗?
答案 0 :(得分:1)
您可以通过将单个组织表替换为具有指示父级的自定义外键的单个组织级来显着简化此数据库设计。
考虑这样的事情:
CREATE TABLE ORGANIZATION
( org_id int IDENTITY NOT NULL
, org_level CHAR(1) NOT NULL
, [name] VARCHAR(50) NOT NULL
, parent_org_id INT
, constraint pk_org PRIMARY KEY (org_id)
, constraint fk_org_hierarchy FOREIGN KEY (parent_org_id)
REFERENCES ORGANIZATION (org_id)
, constraint ck_org_level CHECK
( org_level = 'B' -- Bureau
OR org_level = 'O' -- Office
OR org_level = 'D')-- Division
, constraint ck_org_root CHECK
( (org_level = 'B' AND parent_org_id IS NULL)
OR (org_level <> 'B' AND parent_org_id IS NOT NULL) )
);
现在,您将所有组织级别都放在一个表中,这意味着您的所有多对多交叉表也可以从三个拆分为一个,并且您可以分配其他外键关系,例如一个从project
到组织的任何级别。
请注意,您也可以添加其他约束,以便您可以强制执行业务规则,例如:
4.每个项目都需要由至少一名员工管理,具有特定角色(项目经理)的员工表很难 由具有其他角色,甚至多个角色的个人组成。
要记住的一件事是管理关系数据库中的分层数据有点棘手。但是,有些事情可以让你更简单。例如,有关管理RDBMS中的层次结构的更多信息,请参阅my answer to this question。