六天帶你玩轉mysql資料庫--第五天筆記(上)
阿新 • • 發佈:2018-11-08
回顧:
連線查詢:多張表連線到一起,不管記錄數如何,欄位數一定會增加。 分類:內連線,外連線,自然連線和交叉連線。 交叉連線: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一定只有一個值(一行一列)
列子查詢: