约束而不是触发器(具体问题)

时间:2009-11-25 04:43:55

标签: sql database database-design triggers constraints

我在这里阅读了使用约束而不是触发器的一些原因。但我怀疑。如何确保(仅使用约束),SUPERCLASS表和SUBCLASSES表之间的一致性?

在INS .. UPD ...

时,只需检查一个触发器

有没有办法通过仅使用约束来定义那种关系(我是新手),谢谢!

3 个答案:

答案 0 :(得分:2)

您可以使用约束来确保每个ContractEmployees行都有一个对应的Employees行,对于SalariedExployees也是如此。我不知道使用约束来强制执行相反的方法:确保对于每个Employees行,在ContractEmployees或SalariedEmployees中都有一行。

备份...在关系数据库中有三种主要方法来模拟OO继承。术语来自Martin Fowler的企业应用程序架构模式

  1. 单表继承:一切都在一个大表中,有很多可选列只适用于某些子类。容易做但不是很优雅。

  2. 具体表继承:每种具体类型一个表。因此,如果所有员工都是受薪或合​​同,那么您将有两个表:SalariedEmployees和ContractEmployees。我也不喜欢这种方法,因为它使得查询所有员工更加困难,无论其类型如何。

  3. 类表继承:基类的一个表和每个子类的一个表。所以有三个表:Employees,SalariedEmployeees和ContractEmployees。

  4. 以下是带有约束的类表继承示例(MS SQL Server的代码):

    CREATE TABLE Employees 
    (
      ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
      FirstName VARCHAR(100) NOT NULL DEFAULT '',
      LastName VARCHAR(100) NOT NULL DEFAULT ''
    );
    
    CREATE TABLE SalariedEmployees
    (
      ID INT NOT NULL PRIMARY KEY REFERENCES Employees(ID),
      Salary DECIMAL(12,2) NOT NULL
    );
    
    CREATE TABLE ContractEmployees
    (
      ID INT NOT NULL PRIMARY KEY REFERENCES Employees(ID),
      HourlyRate DECIMAL(12,2) NOT NULL
    );
    

    两个子类表上的“REFERENCES Employees(ID)”部分定义了外键约束。这可确保在SalariedEmployees或ContractEmployees中的每一行的Employees中都必须有一行。

    ID列是将所有内容链接在一起的内容。在子类表中,ID既是该表的主键,也是指向基类表的外键。

答案 1 :(得分:1)

数据库是关系型的,约束很好地强制执行关系依赖性,现在已经这样做了大约30年。你谈到的这个超级和子课程是什么?

<强>更新

在数据库中引入OO继承关系实际上很成问题。举个例子,合同雇员和全职雇员。您可以将其建模为1)具有鉴别器字段的单个表,2)两个不相关的表,或3)三个表(一个具有公共部分,一个具有合同特定信息,一个具有全时特定信息)。

但是,如果从传统的正常形式的角度来看同样的问题,你可能会得到一个类似于1)或3)的结构,但绝不会像2)那样。通常情况下,你最终会得到一些看起来没有你从OO设计板上推荐的东西。

问题在于,当这种需求碰撞发生时,今天几乎总是以OO设计为准。通常情况下,关系模型甚至不会出现在桌面上。为什么我认为这是一个“问题”,大多数时候数据库远远超过其原始应用程序。我经常看到一些设计可以追溯到一个被遗忘的应用程序的OO域驱动设计会话,并且可以在数据库模式中看到随着时间的推移,OO设计被“锤击”到位的地方适合下面的关系引擎可以支持,扩展和交付。对我来说,tell标志是在没有人询问特定ID的表时,围绕身份ID在聚簇索引上组织的表。

答案 2 :(得分:1)

以下是我为合同与薪资员工设置建模的方式:

EMPLOYEE_TYPE_CODE

  • EMPLOYEE_TYPE_CODE,pk
  • DESCRIPTION

示例:

EMPLOYEE_TYPE_CODE     DESCRIPTION
-----------------------------------
CONTRACT               Contractor
SALARY                 Salaried
WAGE_SLAVE             I can't be fired - slaves are sold

EMPLOYEES

  • EMPLOYEE_ID,pk
  • EMPLOYEE_TYPE_CODEEMPLOYEE_TYPE_CODE表的外键
  • 名字,姓氏等。

如果您想要存储层次关系,请说明员工和经理(根据定义,他们也是员工):

EMPLOYEES

  • EMPLOYEE_ID,pk
  • EMPLOYEE_TYPE_CODEEMPLOYEE_TYPE_CODE表的外键
  • MANAGER_ID

MANAGER_ID将填充作为其经理的员工的employee_id。此设置假定员工只能拥有一名经理。如果您在电影“Office Space”中看到的地方工作,您需要一个不同的设置,以允许员工记录与2个以上的经理联系:

MANAGE_EMPLOYEES_XREF

  • MANAGER_EMPLOYEE_ID,pk,fk到EMPLOYEES表
  • EMPLOYEE_ID,pk,fk到EMPLOYEES表