1. 程式人生 > >六天帶你玩轉mysql資料庫--第五天筆記(上)

六天帶你玩轉mysql資料庫--第五天筆記(上)

回顧:

連線查詢:多張表連線到一起,不管記錄數如何,欄位數一定會增加。
	分類:內連線,外連線,自然連線和交叉連線。
	交叉連線:cross  join(笛卡爾積)
	內連線:inner  join,左右兩張表中有連線條件匹配(不忽略的匹配)
	外連線:outer  [left/right]  join,主表有的記錄一定會存在,匹配了就保留副表字段資料,沒匹配就將副表字段置空。
	自然連線:natural  join,自動匹配條件(相同的欄位名),using關鍵字可以將內外連線轉換成自然連線。
PHP操作mysql:
	PHP充當客戶端,開啟mysql擴充套件
	連線認證:mysql_connect;傳送SQL獲取結果:mysql_query;解析結果集:mysql_fetch系列;釋放資源:mysql_free_result
	和mysql_close;錯誤處理:mysql_ermo和mysql_error。

外來鍵:

外來鍵:foreign  key,外面的鍵(鍵不在自己的表中);如果一張表中有一個欄位(非主鍵)指向另外一張表的主鍵,
那麼將該欄位叫為外來鍵。一張表可以有多個外來鍵。

增加外來鍵:

外來鍵可以在建立表的時候或者建立表之後增加(但是要考慮資料的問題)
1.在建立表的時候增加外來鍵:在所有的欄位之後,使用foreign  key(外來鍵欄位)  references  外部表
-- 建立外來鍵 
create table my_foreign1(
id int primary key auto_increment,
name varchar(20) not null comment '學生姓名',
c_id int comment '班級ID',
-- 增加外來鍵
foreign key(c_id) references my_class(id)
)charset utf8;

確保my_class表有主鍵:
在這裡插入圖片描述
在這裡插入圖片描述

在新增表之後增加外來鍵:修改表結構
alter  table  表名  addconstraint  外來鍵名字] foreign  key(外來鍵欄位)  references  父表(主鍵欄位)
-- 建立表
create table my_foreign2(
id int primary key auto_increment,
name varchar(20) not null comment '學生姓名',
c_id int comment '班級ID'    -- 普通欄位
)charset utf8;

-- 增加外來鍵
alter table my_foreign2 add
-- 指定外來鍵名
constraint student_class_1
-- 指定外來鍵欄位
foreign key(c_id)
-- 引用父表主鍵
references my_class(id);

在這裡插入圖片描述

修改外來鍵&刪除外來鍵

外來鍵不可以修改:只能先刪除再新增
刪除外來鍵:alter  table  表名  drop  foreign  key  外來鍵名;  -- 一張表中可以有多個外來鍵,外來鍵名字不可以相同
-- 刪除外來鍵
alter table my_foreign1 drop foreign key my_foreign_ibfk_1;

在這裡插入圖片描述

外來鍵(預設約束)

外來鍵預設的作用有兩點:一個對父表,一個對子表(外來鍵欄位所在的表)
對子表的約束:子表資料進行寫操作的時候,如果對應的外來鍵欄位在父表找不到對應的匹配,那麼操作會失敗(約束子表資料操作)
-- 插入資料:外來鍵欄位在父表中不存在
insert into my_foreign2 values(null,'xff',4);  --沒有4班級

在這裡插入圖片描述

對父表約束:父表資料進行寫操作(刪和改:都必須涉及到主鍵本身),如果對應的主鍵在子表中已經被資料所引用,
那麼就不允許操作。
insert into my_foreign2 values(null,'xfd',1);
insert into my_foreign2 values(null,'xfs',2);
insert into my_foreign2 values(null,'xff',2);

在這裡插入圖片描述

-- 更新父表記錄
update my_class set id = 4 where id = 1;
update my_class set id = 4 where id = 3;

在這裡插入圖片描述

外來鍵的條件:

1.外來鍵要存在:首先要保證表的儲存引擎是innodb(預設的儲存引擎);如果不是innodb儲存引擎,那麼外來鍵可以建立成功,
但是沒有約束效果。
2.外來鍵欄位的欄位型別(列型別)必須與父表的主鍵型別完全一致。
3.一張表中的外來鍵名字不能重複。
4.增加外來鍵的欄位(資料已經存在),必須保證資料與父表主鍵對應。
-- 增加外來鍵
alter table my_foreign1 add foreign key(c_id) references my_class(id); 

在這裡插入圖片描述

外來鍵約束:

所謂外來鍵約束:就是指外來鍵的作用,之前所講的外來鍵的作用:是預設的作用,其實可以通過對外來鍵的需求,進行定製操作。
外來鍵約束有三種模式:都是針對父表的約束
	distinct:嚴格模式(預設的),父表不能刪除或者更新一個已經被子表資料引用的記錄。
	cascade:級聯模式:父表的操作對應子表關聯的資料也跟著操作。
	set  null:置空模式:父表操作之後,子表對應的資料(外來鍵欄位被置空)

通常的一個合理的約束模式:刪除的時候子表置空,更新的時候子表級聯操作。
指定模式的語法:foreign  key(外來鍵欄位)  references  父表(主鍵欄位)  on  delete 模式  update  模式;
foreign  key(外來鍵欄位)  references  父表(主鍵欄位)  on  delete set null  on  update  cascade;
-- 建立外來鍵:指定模式:刪除置空,更新級聯
create table my_foreign3(
id int primary key auto_increment,
name varchar(20) not null,
c_id int,
-- 增加外來鍵
foreign key(c_id)
-- 引用表
references my_class(id)
-- 指定刪除模式
on delete set null
-- 指定更新模式
on update cascade
)charset utf8;

在這裡插入圖片描述
在這裡插入圖片描述

-- 插入資料
insert into my_foreign3 values(null,'劉備',1),
(null,'曹操',1),
(null,'孫權',1),
(null,'諸葛亮',2),
(null,'周瑜',2);

在這裡插入圖片描述
在這裡插入圖片描述

更新操作:級聯更新

-- 更新父表主鍵
update my_class set id = 3 where id = 1;

在這裡插入圖片描述

刪除操作:置空模式

-- 刪除父表主鍵
delete from my_class where id = 2;

在這裡插入圖片描述

刪除置空的前提條件:外來鍵欄位允許為空(如果不滿足條件,外來鍵無法建立),外來鍵雖然很強大,能夠進行各種約束,但是
對於PHP來講,外來鍵的約束降低了PHP對資料的可控性,在實際開發中很少使用外來鍵來處理。

聯合查詢:

聯合查詢:將多次查詢(多條select語句),在記錄上進行拼接(欄位不會增加)
基本語法:
多條select語句:每一條select語句獲取的欄位數必須嚴格一致(但是欄位型別無所謂)
select  語句1  
Union  [union  選項]
select  語句2...

union選項與select選項一樣有兩個:All:保留所有(不管重複);distinct:去重(整個重複,預設的方式)
-- 聯合查詢
select * from my_class
union -- 預設去重
select * from my_class;

select * from my_class
union all -- 不去重
select * from my_class;

在這裡插入圖片描述

聯合查詢只要求欄位一樣,跟資料型別無關。

在這裡插入圖片描述

聯合查詢的意義:

1.查詢同一張表的需求不同的資訊:如查詢學生資訊,男生身高升序,女生身高降序。
2.多表查詢:前提保證多張表的結構是完全一樣的。

order by的使用

在聯合查詢中,order  by不能直接使用,需要對查詢語句使用括號才行。

在這裡插入圖片描述

若要order  by生效,必須搭配limit,limit使用限定最大數即可。

在這裡插入圖片描述

子查詢:

子查詢:sub  query,查詢是在某個查詢結果之上進行的(一條select語句內部包含另外一條select語句)
子查詢的分類:
按位置分類:子查詢(select  語句)在外部查詢(select  語句)中出現的位置。
	from子查詢:子查詢跟在from之後
	where子查詢:子查詢出現在where條件中
	exists子查詢:子查詢出現在exists中
按結果分類:根據子查詢得到的資料進行分類(理論上講任何一個查詢得到的結果都可以理解為二維表)
	標量子查詢:子查詢得到的結果是一行一列
	列子查詢:子查詢得到的結果是一列多行
	行子查詢:子查詢得到的結果是多行一列(多行多列)
		上面幾個子查詢出現的位置都在where之後
	表子查詢:子查詢得到的結果是多行多列(出現的位置在from之後)

標量子查詢:

需求:知道班級名字為PHP0710,想獲取該班的所有學生。
-- 標量子查詢
select * from my_student where c_id = (select id from my_class where c_name = 'php0710');
1.確定資料來源,獲取所有的學生:select  *  from  my_student  where  c_id = ?;
2.獲取班級ID,可以通過班級名字確定:
select  id  from  my_class  where  c_name = 'php0710'; -- ID一定只有一個值(一行一列)

在這裡插入圖片描述

列子查詢: