如何绕过这个必须具有唯一名称的外键约束?

时间:2009-07-11 21:26:14

标签: sql mysql foreign-keys

我不确定为什么这些必须是唯一的,但是从阅读MySQL论坛看来它们确实如此。但是,我认为它与INDEX名称有更多关系。我有两个表具有引用第三个表上的相同主键的外键约束。如果它有帮助,我正在使用MySQL工作台来设计架构。

我通常在每个表上将我的外键命名为与它引用的主键相同的名称。我想这是不可能的。它将使用外键约束创建第一个表,但是当它尝试创建第二个表时会抛出错误。这是它抛出错误的第二个表:

CREATE  TABLE IF NOT EXISTS `joe`.`products_to_categories` (
  `product_to_category_id` INT NOT NULL AUTO_INCREMENT ,
  `category_id` INT NOT NULL ,
  `product_id` INT NOT NULL ,
  PRIMARY KEY (`product_to_category_id`) ,
  INDEX `category_id` (`category_id` ASC) ,
  INDEX `product_id` (`product_id` ASC) ,
  CONSTRAINT `category_id`
    FOREIGN KEY (`category_id` )
    REFERENCES `joe`.`categories` (`category_id` )
    ON DELETE CASCADE
    ON UPDATE NO ACTION,
  CONSTRAINT `product_id`
    FOREIGN KEY (`product_id` )
    REFERENCES `joe`.`products` (`product_id` )
    ON DELETE CASCADE
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

我希望外键名与其他两个表中的主键相同。我应该删除什么,以便我可以使用这些名称。这里的最佳做法是什么。

3 个答案:

答案 0 :(得分:2)

这是不可能的,因为您在用于索引IIRC的文件的文件名中会发生冲突。我可能会把钥匙命名为< tablename> _< column_name>或类似的东西。

答案 1 :(得分:1)

您正在通过名称product_id创建索引(约束): INDEX product_id

然后你要创建另一个具有相同名称的约束(对于外键): 约束product_id

您需要做的是允许服务器通过删除提供默认的唯一约束名称 约束product_id

请参阅此网址:http://dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html

“如果给出了CONSTRAINT符号子句,则符号值在数据库中必须是唯一的。如果没有给出该子句,InnoDB会自动创建名称。”

答案 2 :(得分:0)

在PostgreSQL中,命名索引的默认值是分别将“_pkey”和“_fkey”附加到主键和外键的名称。所以你的情况应该是这样的:

INDEX `product_id_fkey` (`product_id` ASC) ,

更新:我刚试过这个并且有效。看看你的想法是否正确。

    use test;

create table if not exists test.product
(
    product_id int not null auto_increment,
    name varchar(80) not null,
    primary key(product_id)
);

create table if not exists test.category
(
    category_id int not null auto_increment,
    name varchar(80) not null,
    primary key(category_id)
);

create table if not exists test.product_category
(
    product_id int,
    category_id int,
    primary key(product_id, category_id),
    constraint product_id_fkey
        foreign key(product_id) references product(product_id)
        on delete cascade
        on update no action,
    constraint category_id_fkey
        foreign key(category_id) references category(category_id)
        on delete cascade
        on update no action
);

insert into test.product(name) values('teddy bear');
insert into test.category(name) values('toy');
insert into test.product_category 
    select p.product_id, c.category_id from product as p, category as c
    where p.name = 'teddy bear' and c.name = 'toy';