跨越多个表的UNIQUE索引

时间:2013-12-04 15:34:33

标签: mysql sql database-design foreign-keys unique-index

我有以下架构。如何确保child中的所有值对于给定的child.group_id,child.type和parent.status都是唯一的?请注意父母与子女之间的一对一关系。如果父和子是一个表,一个简单的UNIQUE索引可以工作,但是,我希望保持两个表分开。理想情况下,不会使用存储过程,但是,如果需要,我会向他们开放。我使用的是最新版本的MySQL。谢谢

CREATE  TABLE IF NOT EXISTS group (
  id INT NOT NULL AUTO_INCREMENT ,
  moreData VARCHAR(45) NULL ,
  PRIMARY KEY (id) )
ENGINE = InnoDB;

CREATE  TABLE IF NOT EXISTS parent (
  id INT NOT NULL AUTO_INCREMENT ,
  status VARCHAR(45) NOT NULL ,
  moreData VARCHAR(45) NULL ,
  PRIMARY KEY (id) )
ENGINE = InnoDB;

CREATE  TABLE IF NOT EXISTS child (
  parent_id INT NOT NULL ,
  group_id INT NOT NULL ,
  type INT NOT NULL ,
  moreData VARCHAR(45) NULL ,
  PRIMARY KEY (parent_id) ,
  INDEX fk_child_group1_idx (group_id ASC) ,
  CONSTRAINT fk_child_parent
    FOREIGN KEY (parent_id )
    REFERENCES parent (id )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT fk_child_group1
    FOREIGN KEY (group_id )
    REFERENCES group (id )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

2 个答案:

答案 0 :(得分:2)

我认为你正在寻找这些方面的东西。

在“parent”中创建重叠约束。 (“id”列是唯一的,因此{id,any-other-column}也必须是唯一的。)

CREATE  TABLE IF NOT EXISTS parent (
  id INT NOT NULL AUTO_INCREMENT ,
  status VARCHAR(45) NOT NULL ,
  moreData VARCHAR(45) NULL ,
  PRIMARY KEY (id),
  UNIQUE (id, status) 
)
ENGINE = InnoDB;

在“child”中添加状态列。

CREATE  TABLE IF NOT EXISTS child (
  parent_id INT NOT NULL ,
  parent_status VARCHAR(45) NOT NULL ,
  group_id INT NOT NULL ,
  type INT NOT NULL ,
  moreData VARCHAR(45) NULL ,

主键约束 无法更改。

  PRIMARY KEY (parent_id) ,
  INDEX fk_child_group1_idx (group_id ASC) ,

参考这对列。

  CONSTRAINT fk_child_parent
    FOREIGN KEY (parent_id, parent_status )
    REFERENCES parent (id, status )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT fk_child_group1
    FOREIGN KEY (group_id )
    REFERENCES group (id )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION) ,

是否应该在fk_child_parent中级联更新取决于应用程序。给出一些想法。

并在您认为应该唯一的列集上添加唯一约束。

  CONSTRAINT uq_child
    UNIQUE (group_id, type, parent_status)
    REFERENCES group (id)) 
 ENGINE = InnoDB;

答案 1 :(得分:1)

一个选项是创建before insert触发器来执行此验证,mysql不支持check constraints,因此这不是一个选项。