2009-10-16 175 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