溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

MySQL 外鍵約束和表關(guān)系有什么聯(lián)系

發(fā)布時(shí)間:2021-06-18 14:05:13 來(lái)源:億速云 閱讀:166 作者:chen 欄目:開(kāi)發(fā)技術(shù)

這篇文章主要講解了“MySQL 外鍵約束和表關(guān)系有什么聯(lián)系”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“MySQL 外鍵約束和表關(guān)系有什么聯(lián)系”吧!

目錄
  • 外鍵(Foreign Key)

  • 如何確定表關(guān)系

  • 如何建立表關(guān)系

    • 一對(duì)多關(guān)系 - 員工表和部門表

    • 多對(duì)多

    • 一對(duì)一

  • 表關(guān)系總結(jié)

    外鍵(Foreign Key)

    按照上述所說(shuō),一張表存儲(chǔ)員工信息會(huì)極大的浪費(fèi)資源,重復(fù)數(shù)據(jù)太多,這個(gè)問(wèn)題就類似于將所有的代碼都寫(xiě)在了一個(gè)py文件中,因此我們可以將一個(gè)表拆成不同的表,在這不同的表之間建立關(guān)聯(lián),而建立關(guān)聯(lián)就需要使用外鍵foreign key。外鍵也屬于約束條件的一種。

    如何確定表關(guān)系

    表與表之間的關(guān)系有三種一對(duì)多、多對(duì)多、一對(duì)一。那么如何確定表與表之間的關(guān)系呢?

    在確定表與表之間的關(guān)系時(shí)建議換位思考,什么意思呢?就是分別站在兩張表的角度去考慮,比如員工表和部門表的關(guān)系:

    先站在員工表的角度:?jiǎn)T工表中一個(gè)員工能否屬于多個(gè)部門呢?答案是不能

    再站在部門表的角度:部門表中一個(gè)部門能否有多個(gè)員工呢?答案是可以

    因此員工表與部門表是單向的一對(duì)多,那么員工表和部門表就是一對(duì)多的關(guān)系。

    如何建立表關(guān)系

    在建立表關(guān)系時(shí),表與表之間的關(guān)聯(lián)通常以主鍵id作為關(guān)聯(lián)字段。

    一對(duì)多關(guān)系 - 員工表和部門表

    在MySQL的關(guān)系在沒(méi)有多對(duì)一的概念,一對(duì)多和多對(duì)一都是一對(duì)多。在創(chuàng)建一對(duì)多表關(guān)系時(shí)需要遵循以下幾點(diǎn):

    第一,外鍵字段建立在多的一方,即員工表

    第二,在創(chuàng)建表的時(shí)候,一定要先創(chuàng)建被關(guān)聯(lián)一方,即部門表

    第三,在錄入數(shù)據(jù)的時(shí)候也必須先錄入被關(guān)聯(lián)表的數(shù)據(jù),即部門表的數(shù)據(jù)

    第四,當(dāng)不同的表建立關(guān)系時(shí),需要進(jìn)行級(jí)聯(lián)更新和刪除也可以稱為同步更新同步刪除,如果不建立級(jí)聯(lián)更新和刪除的話,無(wú)法對(duì)被關(guān)聯(lián)表中被關(guān)聯(lián)的數(shù)據(jù)進(jìn)行刪除或者修改id的操作,因?yàn)閮蓮埍硎窍嗷リP(guān)聯(lián)的。

    -- 創(chuàng)建被關(guān)聯(lián)表,部門表
    mysql> create table bm(
        id int primary key auto_increment, 
        bm_name varchar(10), 
        bm_desc char(64)
    );
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> desc bm;
    +---------+-------------+------+-----+---------+----------------+
    | Field   | Type        | Null | Key | Default | Extra          |
    +---------+-------------+------+-----+---------+----------------+
    | id      | int(11)     | NO   | PRI | NULL    | auto_increment |
    | bm_name | varchar(10) | YES  |     | NULL    |                |
    | bm_desc | char(64)    | YES  |     | NULL    |                |
    +---------+-------------+------+-----+---------+----------------+
    3 rows in set (0.01 sec)
    
    -- 創(chuàng)建外鍵所在的表,員工表
    mysql> create table yg(
        id int primary key auto_increment, 
        yg_name varchar(6), 
        bm_id int, 
        foreign key(bm_id) references bm(id)  -- 表示bm_id是外鍵字段,關(guān)聯(lián)到bm表中的id字段
        on update cascade  # 級(jí)聯(lián)更新
        on delete cascade  # 級(jí)聯(lián)刪除
    );
    Query OK, 0 rows affected (0.10 sec)
    
    mysql> desc yg;
    +---------+------------+------+-----+---------+----------------+
    | Field   | Type       | Null | Key | Default | Extra          |
    +---------+------------+------+-----+---------+----------------+
    | id      | int(11)    | NO   | PRI | NULL    | auto_increment |
    | yg_name | varchar(6) | YES  |     | NULL    |                |
    | bm_id   | int(11)    | YES  | MUL | NULL    |                |
    +---------+------------+------+-----+---------+----------------+
    3 rows in set (0.01 sec)
    
    
    -- 插入數(shù)據(jù)
    mysql> insert into bm (bm_name, bm_desc) values ('python', '人生苦短'),('go', 'let us go');
    Query OK, 2 rows affected (0.00 sec)
    Records: 2  Duplicates: 0  Warnings: 0
    
    mysql> select * from bm;
    +----+---------+--------------+
    | id | bm_name | bm_desc      |
    +----+---------+--------------+
    |  1 | python  | 人生苦短     |
    |  2 | go      | let us go    |
    +----+---------+--------------+
    2 rows in set (0.00 sec)
    
    
    mysql> insert into yg (yg_name, bm_id) values ('xu', 1), ('zhuang', 2), ('lili', 1);
    Query OK, 3 rows affected (0.09 sec)
    Records: 3  Duplicates: 0  Warnings: 0
    
    mysql> select * from yg;
    +----+---------+-------+
    | id | yg_name | bm_id |
    +----+---------+-------+
    |  2 | xu      |     1 |
    |  3 | zhuang  |     2 |
    |  4 | lili    |     1 |
    +----+---------+-------+
    3 rows in set (0.00 sec)
    
    -- 外鍵關(guān)聯(lián)的數(shù)據(jù)必須在被關(guān)聯(lián)表中存在否則會(huì)報(bào)錯(cuò)哦~
    mysql> insert into yg (yg_name, bm_id) values ('xu', 3);
    ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`book_manage`.`yg`, CONSTRAINT `yg_ibfk_1` FOREIGN KEY (`bm_id`) REFERENCES `bm` (`id`))
    
    -- 如果不使用級(jí)聯(lián)更新和刪除的話會(huì)出現(xiàn)下面的錯(cuò)誤,下述的SQL語(yǔ)句后面的文章都會(huì)介紹。。。
    mysql> update bm set id=5 where id=2;  -- 將bm表中id=2的記錄改為id=5
    ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`book_manage`.`yg`, CONSTRAINT `yg_ibfk_1` FOREIGN KEY (`bm_id`) REFERENCES `bm` (`id`))
    
    mysql> delete from bm where id =2;  -- 刪除bm表中id為2的那條記錄
    ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`book_manage`.`yg`, CONSTRAINT `yg_ibfk_1` FOREIGN KEY (`bm_id`) REFERENCES `bm` (`id`))

    多對(duì)多

    多對(duì)多的關(guān)系以書(shū)籍和作者為例進(jìn)行詳細(xì)介紹,為什么書(shū)籍和作者屬于多對(duì)多的關(guān)系呢?

    先站在書(shū)籍表的角度:一本書(shū)是否可以有多個(gè)作者?答案是可以

    再站在作者表的角度:一個(gè)作者是否可以寫(xiě)多本書(shū)?答案是可以

    書(shū)籍表和作者表是雙向的一對(duì)多那么這兩張表的關(guān)系就是多對(duì)多。

    我們先來(lái)創(chuàng)建兩張表:

    -- 創(chuàng)建書(shū)籍表
    create table book(
        id int primary key auto_increment,
        title varchar(32),
        price int,
        author_id int,
        foreign key(author_id) references author(id)
        on update cascade
        on delete cascade
    );
    
    -- 創(chuàng)建作者表
    create table author(
        id int primary key auto_increment,
        name varchar(32),
        age int,
        book_id int,
        foreign key(book_id) references book(id)
        on update cascade
        on delete cascade
    );

    如果按照上述方式創(chuàng)建表的話肯定是不可能成功的,在創(chuàng)建一對(duì)多的表關(guān)系時(shí)我我們說(shuō)要先創(chuàng)建被關(guān)聯(lián)表,也就是沒(méi)有外鍵的表,可是多對(duì)多關(guān)系是雙向的一對(duì)多,每張表中都會(huì)有外鍵的存在,怎么辦呢?解決方案就是創(chuàng)建第三張表,這第三張表用來(lái)專門存儲(chǔ)多對(duì)多關(guān)系的兩張表的關(guān)聯(lián)。

    -- 創(chuàng)建書(shū)籍表
    mysql> create table book(
        id int primary key auto_increment, 
        name varchar(10), 
        price int
    );
    Query OK, 0 rows affected (0.01 sec)
    
    -- 創(chuàng)建作者表
    mysql> create table author(
        id int primary key auto_increment, 
        name varchar(6), 
        age int
    );
    Query OK, 0 rows affected (0.01 sec)
    
    
    -- 創(chuàng)建第三章表,存儲(chǔ)book和author表的關(guān)聯(lián)關(guān)系
    mysql> create table book2author(
        id int primary key auto_increment, 
        author_id int, 
        book_id int, 
        foreign key(author_id) references author(id) 
        on update cascade 
        on delete cascade, 	
        foreign key(book_id) references book(id) 
        on update cascade 
        on delete cascade);
    Query OK, 0 rows affected (0.02 sec)

    一對(duì)一

    如果一張表的字段特別多,每次查詢數(shù)據(jù)時(shí)又不是所有的字段都能用的到,我們就可以將表一一分為二,比如說(shuō)用戶信息表,用戶的信息包括用戶名 密碼 用戶的年齡 用戶的性別 地址 電話等等,可能經(jīng)常用的只有用戶的用戶名和密碼,這種情況我們就可以將一張用戶信息表拆分成用戶基本信息表和用戶詳細(xì)信息表,同樣判斷這兩張表的關(guān)系還是通過(guò)換位思考:

    首先看用戶基本信息表:一個(gè)用戶能否有多個(gè)詳細(xì)信息?答案是不可以;

    再看用戶詳情表:一個(gè)用戶詳情能否屬于多個(gè)用戶?答案是不可以;

    單向的一對(duì)多都不成立,那么兩者之間的表關(guān)系就是一對(duì)一或者沒(méi)有關(guān)系。

    使用SQL語(yǔ)句建立一對(duì)一的外鍵關(guān)系時(shí),外鍵建在任意一方都可以,但是推薦將外鍵建在查詢頻率較高的表中,同樣的,在創(chuàng)建表時(shí)還是先創(chuàng)建被關(guān)聯(lián)表。

    -- 創(chuàng)建用戶詳情表
    create table authordetail(
    	id int primary key auto_increment,
    	phone int,
    	addr varchar(64)
    );
    
    -- 用戶基本信息表
    create table author(
    	id int primary key auto_increment,
        name varchar(32),
        age int,
        authordetali_id int,
        foreign key(authordetali_id) references authordetali(id)
        on update cascade
        on delete cascade
    );

    表關(guān)系總結(jié)

    表關(guān)系建立需要使用外鍵foreign key,判斷表與表之間的關(guān)系通過(guò)換位思考的方式。

    一對(duì)多表關(guān)系:外鍵建在多的一方

    一對(duì)一表關(guān)系:外鍵建在任意一方都可以,推薦建在查詢頻率高的一方

    多對(duì)多表關(guān)系:需要單獨(dú)創(chuàng)建第三張表存儲(chǔ)兩張表的關(guān)聯(lián)關(guān)系

    感謝各位的閱讀,以上就是“MySQL 外鍵約束和表關(guān)系有什么聯(lián)系”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)MySQL 外鍵約束和表關(guān)系有什么聯(lián)系這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

    向AI問(wèn)一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI