MySQL中如何定義外來鍵

2021-08-31 06:32:24 字數 4259 閱讀 8864

假如某個電腦生產商,它的資料庫中儲存著整機和配件的產品資訊。用來儲存整機產品資訊的表叫做pc;用來儲存配件供貨資訊的表叫做parts。

在pc表中有乙個字段,用來描述這款電腦所使用的cpu型號;在parts表中相應有乙個字段,描述的正是cpu的型號,我們可以把它想成是全部cpu的型號列表。

很顯然,這個廠家生產的電腦,其使用的cpu一定是供貨資訊表(parts)中存在的型號。這時,兩個表中就存在一種約束關係(constraint)——pc表中的cpu型號受到parts表中型號的約束。

首先我們來建立parts表:

create table parts (

... 字段定義 ...,

model varchar(20) not null,

... 字段定義 ...

);

接下來是pc表:

create table pc (

... 字段定義 ...,

cpumodel varchar(20) not null,

... 字段定義 ...

};

設定索引

若要設定外來鍵,在參照表 (referencing table,即pc表) 和被參照表(referenced table,即parts表)中,相對應的兩個字段必須都設定索引(index)。

對parts表:

alter table parts add index idx_model (model);

這句話的意思是,為parts表增加乙個索引,索引建立在model欄位上,給這個索引起個名字叫idx_model。

對pc表也類似:

alter table pc add index idx_cpumodel (cpumodel);

事實上這兩個索引可以在建立表的時候就設定。這裡只是為了突出其必要性。

定義外來鍵

下面為兩張表之間建立前面所述的那種「約束」。因為pc的cpu型號必須參照parts表中的相應型號,所以我們將pc表的cpumodel欄位設定為「外來鍵」(foreign key),即這個鍵的參照值來自於其他表。

alter table pc add constraint fk_cpu_model 

foreign key (cpumodel)

references parts(model);

第一行是說要為pc表設定外來鍵,給這個外來鍵起乙個名字叫做fk_cpu_model;第二行是說將本表的cpumodel欄位設定為外來鍵;第三行是說這個外來鍵受到的約束來自於parts表的model欄位。

這樣,我們的外來鍵就搞好了!如果我們試著create一台pc,它所使用的cpu的型號是parts 表中不存在的,那麼mysql會禁止這台pc被create出來。

級聯操作

考慮以下這種情況:

技術人員發現,乙個月之前輸入到parts表中的某個系列的cpu(可能有很多款)的型號全都輸錯了乙個字母,現在需要改正。我們希望的是,當 parts表中那些 referenced column 有所變化時,相應表中的 referencing column 也能自動更正。

可以在定義外來鍵的時候,在最後加入這樣的關鍵字:

on update cascade;

即在主表更新時,子表(們)產生連鎖更新動作,似乎有些人喜歡把這個叫「級聯」操作。

如果把這語句完整的寫出來,就是:

alter table pc add constraint fk_cpu_model 

foreign key (cpumodel)

references parts(model)

on update cascade;

除了cascade外,還有restrict(禁止主表變更)、set null

關於對該文補充:

如果需要在主表刪除記錄時,當子表有對應記錄則不允許刪除,就加上 on delete restrict 。完整案例如下:

兩個表,國家和城市,城市中的country_id是外來鍵。

create table country(

country_id smallint unsigned not null auto_increment,

country varchar(50) not null,

last_update timestamp not null,

primary key(country_id)

)engine=innodb default charset=utf8;

create table city(

city_id smallint unsigned not null auto_increment,

city varchar(50) not null,

country_id smallint unsigned not null,

last_update timestamp not null default current_timestamp on update curren_timestamp,

primary key(city_id),

key idx_fk_country_id (country_id),

constraint fk_city_country foreign key(country_id) references country(country_id) on delete restrict on update cascade

)engine=innodb default charset=utf8;

刪除外來鍵:

刪除外來鍵定義

—————

定義外來鍵的時候articles.member_id外來鍵比articles.category_id子句多了乙個constraint fk_member ?

這個fk_member就是用來刪除外來鍵定義用的,如下所示:

mysql> alter table articles drop foreign key fk_member;

query ok, 1 row affected (0.25 sec)

records: 1 duplicates: 0 warnings: 0

這樣articles.member_id外來鍵定義就被刪除了,但是如果定義時沒有指定constraint fk_symbol (即外來鍵符號)時該怎麼刪除呢?別急,沒有指定時,mysql會自己建立乙個,可以通過以下命令檢視:

mysql> show create table articles;

+———-+————————————+

| table | create table |

+———-+————————————+

| articles | create table `articles` (

`article_id` int(11) unsigned not null auto_increment,

`category_id` tinyint(3) unsigned not null,

`member_id` int(11) unsigned not null,

`title` varchar(255) not null,

primary key (`article_id`),

key `category_id` (`category_id`),

key `member_id` (`member_id`),

constraint `articles_ibfk_1` foreign key (`category_id`) references `categories` (`id`)

) engine=innodb default charset=latin1 |

+———-+————————————+

1 row in set (0.01 sec)

可以看出articles.category_id的外來鍵符號為articles_ibfk_1,因為就可以執行以下命令刪除外來鍵定義:

mysql> alter table articles drop foreign key articles_ibfk_1;

query ok, 1 row affected (0.66 sec)

records: 1 duplicates: 0 warnings: 0

6. 總結

——-引入外來鍵的缺點是會使速度和效能下降,當然外來鍵所帶來的優點還有很多。

MYSQL 外來鍵定義

建立外來鍵的前提 本表的列必須與外來鍵型別相同 外來鍵必須是外表主鍵 外來鍵作用 使兩張表形成關聯,外來鍵只能引用外表中的列的值!指定主鍵關鍵字 foreign key 列名 引用外來鍵關鍵字 references 外來鍵表名 外來鍵列名 事件觸發限制 on delete和on update 可設引...

MYSQL 外來鍵定義

建立外來鍵的前提 本表的列必須與外來鍵型別相同 外來鍵必須是外表主鍵 外來鍵作用 使兩張表形成關聯,外來鍵只能引用外表中的列的值!指定主鍵關鍵字 foreign key 列名 引用外來鍵關鍵字 references 外來鍵表名 外來鍵列名 事件觸發限制 on delete和on update 可設引...

mysql中如何設定外來鍵

概念 表示兩個表之間的相關聯絡,是表與表之間保持資料一致性,完整性,主要目的是控制儲存在外鍵表中的資料,約束,外來鍵只能引用外表中的列的值或使用空值。這兩個表必須滿足三個條件 使用在外鍵關係的域必須與資料型別相似 使用在外鍵關係的域必須為索引型 index 兩個表必須是innodb資料引擎 建立外來...