【问题标题】:Integrity constraint issue in an inheritance relational model with MySQL 5.5MySQL 5.5 继承关系模型中的完整性约束问题
【发布时间】:2011-09-14 10:34:38
【问题描述】:

我有以下数据库关系模式,旨在将 EMP 超类型与两个 FULL_TIME_EMP 和 PART_TIME_EMP 子类型一起建模:

我遇到的问题是完整性问题,即我想确保全职员工在 FULL_TIME_EMP 表中只能有相应的行,同样,兼职员工在 PART_TIME_EMP 表中只能有相应的行。

正如您将在下面的屏幕截图中看到的那样,此完整性约束并未强制执行。

这是 EMP_TYPE 表:

还有 EMP 表:

PART_TIME_EMP 表:

最后是显示完整性违规的 FULL_TIME_EMP 表!!

有没有办法通过改变我的数据库模型设计来强制执行这种完整性约束,还是我必须求助于触发器?

问候,

【问题讨论】:

    标签: mysql database-design database-integrity


    【解决方案1】:

    您没有诉诸触发器,但它可能会有所帮助。改变结构会有很大帮助,但它通常依赖于 CHECK 约束。在 MySQL 中,如果需要 CHECK 约束,则必须编写触发器或添加另一个使用外键约束的表。

    您有额外的负担,因为兼职员工以后可能会成为全职员工,反之亦然。

    我将如何为更标准的 SQL 平台编写它。

    create table emp (
      emp_id integer primary key,
      emp_type char(1) not null check (emp_type in ('f', 'p')), -- FK in your schema
      emp_name varchar(50) not null,
      start_date date not null default current_date,
      unique (emp_id, emp_type)
    );
    
    create table full_time_emp (
      emp_id integer primary key references emp (emp_id),
      emp_type char(1) not null default 'f' check (emp_type = 'f'),
      foreign key (emp_id, emp_type) references emp (emp_id, emp_type),
      salary decimal(14,2) not null check (salary > 15000)
    );
    
    create table part_time_emp (
      emp_id integer primary key references emp (emp_id),
      emp_type char(1) not null default 'p' check (emp_type = 'p'),
      foreign key (emp_id, emp_type) references emp (emp_id, emp_type),
      rate decimal(14,2) not null check (rate > 0 and rate < 100)
    );
    

    在full_time_emp表中,这两个约束

      check (emp_type = 'f'),
      foreign key (emp_id, emp_type) references emp (emp_id, emp_type),
    

    加起来可以防止兼职员工出现在全职工作表中。如果“emp”中引用的行包含“p”,则外键引用将失败;如果您尝试将“p”插入“full_time_emp”,则检查约束将失败。

    在这种情况下,您可以将检查约束替换为单行表和外键引用。该表应仅包含“f”。 (或您用来代表全职员工的任何 ID 号。)同样的事情适用于“part_time_emp”。因此,您可以为 full_time_emp 执行 this,而不是 CHECK 约束。

    create table full_time_emp_check (
      full_time_emp_type char(1) primary key
    );
    insert into full_time_emp_check values ('f');
    
    alter table full_time_emp
    add constraint full_time_emp_check
    foreign key (emp_type) references full_time_emp_check (full_time_emp_type);
    

    part_time_emp 的更改类似。您可能希望在这两个表上都有一个触发器,以确保它们永远不会包含超过一行。

    甚至对薪水和费率的检查也可以通过额外的表和外键引用来实现。不过,有点像在海滩上踢死鲸鱼。我可能会在 MySQL 中使用触发器实现 那种 类型的范围约束。

    恕我直言,对于员工类型,CHAR(1) 代码优于整数。人类可读的代码不需要连接。

    【讨论】:

    • 感谢您提供全面而相关的答案!
    猜你喜欢
    • 2019-02-03
    • 2021-08-03
    • 1970-01-01
    • 2012-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-25
    相关资源
    最近更新 更多