错误1215:使用外键进行数据库设计

时间:2018-06-19 18:16:41

标签: mysql database-design

我正在尝试创建三个表,如员工,经理和出勤。出勤表应该具有其他两个表中的员工和经理详细信息,这应该可以标记出勤。我创建了这个SQL脚本。我不确定我在哪里犯错。

CREATE TABLE associate (
    id      INT             NOT NULL,
    idmanager INT           NOT NULL,
    emp_id  DATE  NOT NULL,
    emp_name VARCHAR(25)  NOT NULL,
    FOREIGN KEY (id)  REFERENCES attendance (associate_id) ON DELETE CASCADE,
    FOREIGN KEY (idmanager)  REFERENCES attendance (manager_idmanager)    ON DELETE CASCADE,
    PRIMARY KEY (id)                  
)   ENGINE=INNODB;

CREATE TABLE manager (
   id       INT     NOT NULL,
   mgr_usr_id VARCHAR(15) NOT NULL,
   mgr_name VARCHAR(25) NOT null,
   KEY         (id),
   KEY         (mgr_usr_id),
   FOREIGN KEY (id)  REFERENCES associate (idmanager)   ON DELETE CASCADE,
   PRIMARY KEY (id)
)  ENGINE=INNODB;

CREATE TABLE attendance (
   sno      INT     NOT NULL,
   manager_idmanager INT    NOT NULL,
   associate_id INT     NOT NULL,
   date_stamp DATETIME,
   state BIT    NOT NULL,
   PRIMARY KEY (sno)
)  ENGINE=INNODB;

屏幕截图

Screenshot

1 个答案:

答案 0 :(得分:1)

这是订购问题。例如,执行的第一条语句是

CREATE TABLE associate (
引用attendance

。但是,attendance表尚未创建。切换顺序,以使引用其他表的任何表都位于最后。

或者,不要将FOREIGN KEY约束放在CREATE语句中,而是在脚本的末尾加上ALTER TABLE语句。考虑:

CREATE TABLE associate (
  id        INT          NOT NULL,
  idmanager INT          NOT NULL,
  emp_id    DATE         NOT NULL,
  emp_name  VARCHAR(25)  NOT NULL,

  PRIMARY KEY (id)
) ENGINE=INNODB;

CREATE TABLE attendance (
  sno               INT       NOT NULL,
  manager_idmanager INT       NOT NULL,
  associate_id      INT       NOT NULL,
  date_stamp        DATETIME,
  state             BIT       NOT NULL,

  PRIMARY KEY (sno)
) ENGINE=INNODB;

ALTER TABLE associate ADD FOREIGN KEY (id) REFERENCES associate(id) ON DELETE CASCADE;

编辑

以上只是语法。要对请求的问题建模,请考虑信息的<正交> 。您可能还会看到/听到“规范化”。基本概念是:仅拥有一份信息副本。架构应具有针对所有数据的单个授权点。例如,如果用户有生日,请确保您没有用于存储其生日的辅助列;它是多余的信息,并可能导致数据错误。

在这种情况下,是什么关系?另一个必须首先存在什么?没有经理可以参加会议吗?没有经理的经理怎么样?前者没有任何意义。那么,在这种情况下,我实际上将使用第三个表来形成层次结构。

然后,考虑角色可能在公司中发生了变化。 DB架构师不应该将角色硬编码为表。考虑:

CREATE TABLE employee (
  id      INTEGER NOT NULL AUTO_INCREMENT,
  name    VARCHAR(25) NOT NULL,
  PRIMARY KEY (id)
) ENGINE=INNODB;

CREATE TABLE role (
  id    INTEGER NOT NULL AUTO_INCREMENT,
  name  VARCHAR(30) NOT NULL,
  description VARCHAR(254) NOT NULL,
  PRIMARY KEY( id ),
  UNIQUE( name )
) ENGINE=INNODB;

INSERT INTO role (name, description) VALUES
  ('associate', 'An associate is a ...'),
  ('manager', 'A manager follows ...');


CREATE TABLE employee_role (
  employee_id  INTEGER NOT NULL,
  role_id      INTEGER NOT NULL,
  PRIMARY KEY (employee_id, role_id),
  FOREIGN KEY (idemployee_id)  REFERENCES employee_id (id) ON DELETE CASCADE,
  FOREIGN KEY (role_id)  REFERENCES role (id) ON DELETE CASCADE
) ENGINE=INNODB;


CREATE TABLE attendance (
   sno               INTEGER NOT NULL,
   employee_id       INTEGER NOT NULL,
   date_stamp        DATETIME,
   state             BIT NOT NULL,
   PRIMARY KEY (sno),
   FOREIGN KEY (idemployee_id)  REFERENCES employee_id (id) ON DELETE CASCADE
)  ENGINE=INNODB;

在此模式下,出席会议只需要一个外键,因为所有人是一名雇员。员工可以担任多个角色,并且可以更改。此外,角色定义可以更改而无需求助于昂贵的DDL语句(数据定义层更改,如ALTER TABLE),并且可以用简单的DML进行修改(数据操作层更改,如UPDATE TABLE)。前者涉及重写表中的所有条目并更改模式,而后者涉及更改单个条目。