2009-10-16 179 views
0

我在尝试为MySql(Innodb)中的表生成外键时遇到了一些问题。你能帮我一起吗?mysql(innodb)外键约束问题

引用的表:

*create table entity 
{ 
    PID INT(20) auto inc not null, 
    ENTITYID INT(20) not null, 
    details VARCHAR(100) not null, 
    primary key(PID,ENTITYID) 
} 
create table user 
{ 
USERID int(20) auto inc not null, 
NAME VARCHAR(45) not null, 
joindate DATETIME not null, 
location VARCHAR(100) not null, 
primary key(USERID,NAME) not null 
}* 

Referencing table: 
*create table C 
{ 
    ENTITYID INT(20) not null, 
    NAME VARCHAR(45) not null, 
    foreign key ENTITYID_C constraint ENTITYID references entity(ENTITYID) on delete cascade, 
    foreign key name_C constraint NAME references user(NAME) on delete cascade, 
    primary key(ENTITYID,NAME) 
}* 

我需要表C中2个外键,因为当任何相应的实体或相应的用户被删除C中的条目必须被删除。

当我尝试创建表C时遇到错误:错误1005:无法创建表(errno:150)。我怀疑这是因为我不遵守mysql规范中规定的规则。 http://dev.mysql.com/doc/refman/5.4/en/innodb-foreign-key-constraints.html

规范的下面部分/规则是什么意思?

“InnoDB需要外键和引用键的索引,以便外键检查可以很快并且不需要表扫描。在引用表中,必须有一个索引,其中外键列被列为第一个列顺序相同“。

这是否意味着表C中的外键需要与实体表和用户表中的主键相对应,这样实体表中的ENTITYID必须是主键中的第一个键,并且用户表中的NAME必须是第一个主键。 换句话说,我的主键声明应该被重写如下:

entity table --> primary key(ENTITYID,PID) , 
user table --> primary key(NAME,USERID) 

如果是这样,当我试图如上我碰上错误1075 重新排序的关键声明“不正确的表定义,只能有一个自动柱,它必须定义为一个关键。”

如何使自动递增键(代理键)在索引顺序列表中排在第二位,以便符合规范?

谢谢!

回答

1

我不认为你的实体和用户的主键是正确的。我相信你有主键和索引混在一起。

您有两个表的自动增量列。我认为这些应该是主键 - ENTITY的PID,USER的USERID。如果您使用ENTITYID查询实体,或者使用NAME查询USER,则通过所有方法都可以为两者创建索引。

现在,表C定义了ENTITY和USER之间的多对多关系。 C中有两列指向PID和USERID,每个列都有外键。 C上的主键只是两者的组合。

像这样:

create table entity 
{ 
    pid int(20) auto inc not null, 
    primary key(pid) 
}; 

create table user 
{ 
    userid int(20) auto inc not null, 
    primary key(userid) 
}; 

create table user_entity 
{ 
    entity_id int(20) not null, 
    user_id int(20) not null, 
    primary key(entity_id, user_id) 
    foreign key entity_id references entity(pid) on delete cascade, 
    foreign key user_id references user(userid) on delete cascade 
}; 
+0

感谢您为您的文章! 我正在重新设计我的表格以避免这些问题。 – user190914 2009-10-17 20:05:24

0

每当我这样做我绝对,绝对发现,最好是先定义所有的表,再后来有独立的ALTER查询申请的约束。你避免了这么多“我需要这张桌子先存在”的问题等等。

1

Ollie Saunders是正确的。 在删除/创建InnoDB表之前,首先删除所有约束。

ALTER TABLE tbl_name 
    ADD [CONSTRAINT [symbol]] FOREIGN KEY 
    [index_name] (index_col_name, ...) 
    REFERENCES tbl_name (index_col_name,...) 
    [ON DELETE reference_option] 
    [ON UPDATE reference_option] 

来源:Alter table syntax