1. 程式人生 > >編程之路:MySql系列表之間的關系

編程之路:MySql系列表之間的關系

OS tro sed 分享圖片 sca pla ces 部門 員工

foreign key

快速理解foreign key

員工信息表有三個字段:工號 姓名 部門

公司有3個部門,但是有1個億的員工,那意味著部門這個字段需要重復存儲,部門名字越長,越浪費

數據放一張表的弊端

1、表的組織結構復雜不清晰

2、浪費空間

3、擴展性差

解決方法:

我們完全可以定義一個部門表

然後讓員工信息表關聯該表,如何關聯,即foreign key

技術分享圖片
#表類型必須是innodb存儲引擎,且被關聯的字段,即references指定的另外一個表的字段,必須保證唯一
create table department(
id int primary key,
name varchar(
20) not null )engine=innodb; #dpt_id外鍵,關聯父表(department主鍵id),同步更新,同步刪除 create table employee( id int primary key, name varchar(20) not null, dpt_id int, constraint fk_name foreign key(dpt_id) references department(id) on delete cascade on update cascade )engine=innodb; #先往父表department中插入記錄 insert into department values (
1,歐德博愛技術有限事業部), (2,艾利克斯人力資源部), (3,銷售部); #再往子表employee中插入記錄 insert into employee values (1,egon,1), (2,alex1,2), (3,alex2,2), (4,alex3,2), (5,李坦克,3), (6,劉飛機,3), (7,張火箭,3), (8,林子彈,3), (9,加特林,3) ; #刪父表department,子表employee中對應的記錄跟著刪 mysql> delete from department where id=3; mysql
> select * from employee; +----+-------+--------+ | id | name | dpt_id | +----+-------+--------+ | 1 | egon | 1 | | 2 | alex1 | 2 | | 3 | alex2 | 2 | | 4 | alex3 | 2 | +----+-------+--------+ #更新父表department,子表employee中對應的記錄跟著改 mysql> update department set id=22222 where id=2; mysql> select * from employee; +----+-------+--------+ | id | name | dpt_id | +----+-------+--------+ | 1 | egon | 1 | | 3 | alex2 | 22222 | | 4 | alex3 | 22222 | | 5 | alex1 | 22222 | +----+-------+--------+ 示範
示範

如何找出兩張表之間的關系

分析步驟:
#1、先站在左表的角度去找
是否左表的多條記錄可以對應右表的一條記錄,如果是,則證明左表的一個字段foreign key 右表一個字段(通常是id)

#2、再站在右表的角度去找
是否右表的多條記錄可以對應左表的一條記錄,如果是,則證明右表的一個字段foreign key 左表一個字段(通常是id)

#3、總結:
#多對一:
如果只有步驟1成立,則是左表多對一右表
如果只有步驟2成立,則是右表多對一左表

#多對多
如果步驟1和2同時成立,則證明這兩張表時一個雙向的多對一,即多對多,需要定義一個這兩張表的關系表來專門存放二者的關系

#一對一:
如果1和2都不成立,而是左表的一條記錄唯一對應右表的一條記錄,反之亦然。這種情況很簡單,就是在左表foreign key右表的基礎上,將左表的外鍵字段設置成unique即可

建立表之間的關系

#一對多或稱為多對一
三張表:出版社,作者信息,書

一對多(或多對一):一個出版社可以出版多本書

關聯方式:foreign key
技術分享圖片
=====================多對一=====================
create table press(
id int primary key auto_increment,
name varchar(20)
);

create table book(
id int primary key auto_increment,
name varchar(20),
press_id int not null,
foreign key(press_id) references press(id)
on delete cascade
on update cascade
);


insert into press(name) values
(北京工業地雷出版社),
(人民音樂不好聽出版社),
(知識產權沒有用出版社)
;

insert into book(name,press_id) values
(九陽神功,1),
(九陰真經,2),
(九陰白骨爪,2),
(獨孤九劍,3),
(降龍十巴掌,2),
(葵花寶典,3)
;
View Code

#多對多
三張表:出版社,作者信息,書

多對多:一個作者可以寫多本書,一本書也可以有多個作者,雙向的一對多,即多對多
  
關聯方式:foreign key+一張新的表
技術分享圖片
=====================多對多=====================
create table author(
id int primary key auto_increment,
name varchar(20)
);


#這張表就存放作者表與書表的關系,即查詢二者的關系查這表就可以了
create table author2book(
id int not null unique auto_increment,
author_id int not null,
book_id int not null,
constraint fk_author foreign key(author_id) references author(id)
on delete cascade
on update cascade,
constraint fk_book foreign key(book_id) references book(id)
on delete cascade
on update cascade,
primary key(author_id,book_id)
);


#插入四個作者,id依次排開
insert into author(name) values(egon),(alex),(yuanhao),(wpq);

#每個作者與自己的代表作如下
egon: 
九陽神功
九陰真經
九陰白骨爪
獨孤九劍
降龍十巴掌
葵花寶典
alex: 
九陽神功
葵花寶典
yuanhao:
獨孤九劍
降龍十巴掌
葵花寶典
wpq:
九陽神功


insert into author2book(author_id,book_id) values
(1,1),
(1,2),
(1,3),
(1,4),
(1,5),
(1,6),
(2,1),
(2,6),
(3,4),
(3,5),
(3,6),
(4,1)
;
View Code

#一對一
兩張表:學生表和客戶表

一對一:一個學生是一個客戶,一個客戶有可能變成一個學校,即一對一的關系

關聯方式:foreign key+unique
技術分享圖片
#一定是student來foreign key表customer,這樣就保證了:
#1 學生一定是一個客戶,
#2 客戶不一定是學生,但有可能成為一個學生


create table customer(
id int primary key auto_increment,
name varchar(20) not null,
qq varchar(10) not null,
phone char(16) not null
);


create table student(
id int primary key auto_increment,
class_name varchar(20) not null,
customer_id int unique, #該字段一定要是唯一的
foreign key(customer_id) references customer(id) #外鍵的字段一定要保證unique
on delete cascade
on update cascade
);


#增加客戶
insert into customer(name,qq,phone) values
(李飛機,31811231,13811341220),
(王大炮,123123123,15213146809),
(守榴彈,283818181,1867141331),
(吳坦克,283818181,1851143312),
(贏火箭,888818181,1861243314),
(戰地雷,112312312,18811431230)
;


#增加學生
insert into student(class_name,customer_id) values
(脫產3班,3),
(周末19期,4),
(周末19期,5)
;
View Code

修改表ALTER TABLE

語法:
1. 修改表名
      ALTER TABLE 表名 
                          RENAME 新表名;

2. 增加字段
      ALTER TABLE 表名
                          ADD 字段名  數據類型 [完整性約束條件…],
                          ADD 字段名  數據類型 [完整性約束條件…];
      ALTER TABLE 表名
                          ADD 字段名  數據類型 [完整性約束條件…]  FIRST;
      ALTER TABLE 表名
                          ADD 字段名  數據類型 [完整性約束條件…]  AFTER 字段名;
                            
3. 刪除字段
      ALTER TABLE 表名 
                          DROP 字段名;

4. 修改字段
      ALTER TABLE 表名 
                          MODIFY  字段名 數據類型 [完整性約束條件…];
      ALTER TABLE 表名 
                          CHANGE 舊字段名 新字段名 舊數據類型 [完整性約束條件…];
      ALTER TABLE 表名 
                          CHANGE 舊字段名 新字段名 新數據類型 [完整性約束條件…];

復制表

復制表結構+記錄 (key不會復制: 主鍵、外鍵和索引)
mysql> create table new_service select * from service;

只復制表結構
mysql> select * from service where 1=2;        //條件為假,查不到任何記錄
Empty set (0.00 sec)
mysql> create table new1_service select * from service where 1=2;  
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> create table t4 like employees;

刪除表

DROP TABLE 表名;

編程之路:MySql系列表之間的關系