带条件外键的数据库模型

时间:2015-04-19 10:20:59

标签: database ms-access database-design relational-database

我需要使用以下条件建模数据库:

  • Projects
  • 的一个表格
  • Programmers
  • 的另一个表格
  • 程序员可以是SeniorJunior
  • 每个项目可能有几个程序员,但至少一个高级必须存在。

我想定义某种有条件的外键,以确保包含在项目中的所有程序员中至少有一个是高级的。也没有高级程序员可以降级为初级,尽管可能会发生相反的情况。

我不知道如何在不诉诸某些业务逻辑的情况下创建这种约束。

2 个答案:

答案 0 :(得分:0)

不幸的是,你必须依靠一些业务逻辑来实现你想要的目标。

您可以将Senior和Junior的属性约束为这两个值,但不能在表级别显示升级功能。

你想要的基本上是一个检查某些约束但触发器不支持数据库触发器的触发器。解决方法是使高级 - 初级属性仅在表单中可变。在此表单中,您将AfterUpdate事件或BeforeUpdate事件连接到绑定到该属性的文本框,并通过VBA代码检查业务逻辑。

同样适合你的至少一个高级约束。

某些代码会进一步帮助吗?

答案 1 :(得分:0)

有时可以考虑使用两种不同的约束而不是一种具有特殊条件的约束。

例如,条件1:每个项目必须有一个高级程序员分配给它;条件2:每个项目可以分配任意数量的高级或初级程序员。

create table Programmers(
    ID     counter constraint PK_Programmers primary key,
    Name   text,
    Seniority char( 1 ) check( Seniority in( 'S', 'J' ),
    ...,
    constraint UQ_Programmer_seniority unique( ID, Seniority ),
    constraint CK_Programmer_Seniority check( Seniority in( 'S', 'J' ))
);
create table Project(
    ID     counter constraint PK_Projects primary key,
    Name   text,
    SrProg int,
    SrFlag char( 1 ) default 'S',
    ...,
    constraint SK_Project_SrFlag check( SrFlag = 'S' ),
    constraint FK_Project_SrProgrammer foreign key( SrProg, SrFlag )
        references Programmers( ID, Seniority )
 );

因此,高级程序员是一个1-1 FK,被定义为项目元组的一部分。除非程序员被定义为' S'否则不能进行引用。 (高级),一旦提及,' S'对于该程序员,不能更改为' J'。

对于其他程序员,请使用标准交叉表。由于这些程序员的资历并不重要,只需在参考文献中使用PK。

create table Project_Programmers(
    ProjID    int not null,
    ProgID    int not null,
    constraint PK_Project_Programmers primary key( ProjID, ProgID ),
    constraint FK_Project_Programmers_Project foreign key( ProjID )
        references Projects( ID ),
    constraint FK_Project_Programmers_Programmer foreign key( ProgID )
        references Programmers( ID )
);

因为资历指标不是这些FK的一部分,所以资历指标是' J'可以改为' S'没问题或来自' S'到了J'如果该程序员未被定义为项目的强制性高级程序员。让我们面对它,有时人们必须降级。这为您提供了额外的保护,可以让降级的程序员被指定为 任何项目的高级程序员。除非从所有这些职位中移除,否则无法降级。