1. 程式人生 > >mysql__子查詢及它的一些特寫

mysql__子查詢及它的一些特寫

子查詢

求最高工資的員工資訊
select max(sal),e* from emp e;-- 會報錯

select max(sal) from emp e;
– 最大值 一行記錄 , 但名字有兩個

情況一 把子查詢當成一個值

分解問題

select max(sal) from emp;//把它當做一個值 5000
select * from emp where sal = 5000; --> 第二步:寫主查詢語句 
select * from emp where sal=(select max(sal) from emp); --> 第三步:替換

情況二把子查詢當成一張表

每個部門的最高工資的員工

第一步 按部門分組
(select max(sal) msal,deptno  from emp group by deptno)a
// 生成了臨時表 a, 其中有兩列: msal, deptno
第二步: 把上面的查詢結果看做一張臨時表,它可以與其他表之間做連線操作
select * from emp b inner join a on b.deptno=a.deptno and b.sal = a.msal;

第三步: 把子查詢代入
select * from emp b inner join 
    (select  max(sal) msal, deptno  from
emp group by deptno) a on b.deptno=a.deptno and b.sal = a.msal;

case when

可以配合select 工作,把一列的取值根據不同的條件進行翻譯
類似於java中的if else if
語法

case 
	when 條件一 then 結果一
	when 條件二 then 結果二
	···
	else 條件n then 結果n
end

2000以下顯示低工資,2000~3000顯示中等,3000以上顯示高工資

select empno,ename,sal, 
case 
	when sal<=2000 then '低工資'
when sal>2000 and sal<=3000 then '中等工資' else '高工資' end 工資級別 from emp;

dcl (瞭解)

grant 授權
revoke 回收許可權

建立使用者

create user 使用者名稱 identified by '密碼';

授權語法:

grant 許可權 to 使用者名稱;

例如:把查詢test庫中所有表的查詢許可權授權給user1
grant select on test.* to user1;

回收許可權

revoke 許可權 from 使用者名稱;

例如:回收之前分配的許可權:

revoke select on test.* from user1;

事務和鎖

事務

transaction 事務 : 把多條sql語句視為一個整體執行,這些sql 要麼都成功, 其中有一個失敗了,之前的操作也需要撤銷

兩個人同時操作一張表的同一條資料

中國銀行賬戶表 account
id        name       balance(餘額)
1         張三       2000

建設銀行賬戶
id        name       balance(餘額)
2         張三       3000
張三轉賬
try {
    begin;
    update account set balance=balance+1000 where id = 2;    

     // 出現異常
    update account set balance=balance-1000 where id = 1; 
    commit;
} catch( Exception e ) {
    rollback;
}

mysql的事務控制
預設情況下,是一條語句一個事務
要多條語句一個事務,需要通過 begin(開始) commit (提交)rollback(撤銷) 來控制事務

begin; // 表示事務的起點 等價方式: start transaction
sql1
sql2

commit(提交,表示結果都將生效) 和 rollback(回滾,用來撤銷事務內的更改) 表示事務的終點
TCL (事務控制語言)

鎖(瞭解)

客戶1                                                               客戶2
begin;                                                              begin;
update emp set sal = 4000 where empno = 7369;
                                                            update emp set ename = 'abc' where empno = 7369; // 被阻塞
                                                            直到超時為止

InnoDB 行級鎖, 只要兩個客戶端更新的是不同的行,互不干擾
MyISAM 表鎖,是鎖住整個表

增刪改(insert update delete) 都會在行上加排他鎖(X鎖)
查詢可以加共享鎖 (S鎖)表示可以同時查詢,但其他人不能增刪改(insert update delete)

select * fromlock in share mode;  新增共享鎖-別人可以再加共享鎖,但不能再加排他鎖

查詢時加排他鎖

select * fromfor update;   新增排他鎖, -別人不能再加共享鎖和排他鎖

mysql對查詢有特別的優化:不用鎖也能實現併發訪問: 多版本併發訪問(MVCC)

查詢

1   張三    8000 舊版本
                修改
                1   張三    7000
select * from 表 就是利用的多版本併發查詢, 好處:併發性高!

java.util.concurrent.CopyOnWriteArrayList 執行緒安全的ArrayList: 修改時會產生一個集合的副本,修改都是在副本上進行,查詢查的是舊集合的內容,所以查詢和修改可以並行執行,等修改結束會用副本替換舊的內容
執行緒安全的List: Vector 全部方法加鎖

事務隔離性(瞭解)

有不同的隔離級別,
隔離級別越低,併發性越好,但資料的一致性差
隔離級別越高,併發性差,但資料的一致性高
由低到高四種:
讀未提交 < 讀提交 < 可重複讀(mysql預設) < 序列化讀

錯誤的級別由高到低
髒讀 , 不可重複讀, 幻讀

髒讀(讀未提交)

7369的工資1000
事務1                                              事務2
begin                                              begin
修改7369的工資為8000
                                                   select * sal from emp where empno=7369;// 8000
rollback

將隔離級別提高到讀提交,可以避免髒讀

不可重複讀

一邊查詢,另一邊做update操作
一個事務內多次查詢結果不一致

7369的工資1000
事務1                                              事務2
begin                                              begin
                                                   select * sal from emp where empno=7369; // 1000
修改7369的工資為8000
commit;
                                                   select * sal from emp where empno=7369; // 8000

要避免髒讀、不可重複讀:將隔離級別提高到可重複讀隔離級別

幻讀

一邊查詢,另一邊做insert操作

事務1                                              事務2
begin                                              begin
查詢到10,20,30,40條記錄
                                                   insert 50號部門
                                                   commit
insert 50號部門 報錯,主鍵衝突

要避免髒讀、不可重複讀、幻讀:將隔離級別提高到序列化讀
所謂的序列化讀就是把多版本併發退化到鎖的併發控制:select語句上會被偷偷加上共享鎖

事務四特性 (ACID)

原子性 A 多個sql要作為一個整體執行,不可分割
一致性 C 一個事務內結果應當一致
隔離性 I
永續性 D 事務一旦提交,事務內的修改就應當永久生效

其他sql總結 (瞭解)

檢視有哪些庫: show databases;
檢視庫的建立語句: show create database 庫名;
使用庫: use 庫名;
檢視有哪些表: show tables;
查看錶結構: desc 表名;
檢視建表語句: show create table 表名;
\G 可以取代; 效果是把錶行轉列
檢視系統變數的值: select @@系統變數名;

select @@transaction_isolation; // 檢視事務隔離級別
select @@port; // 檢視伺服器埠號
select @@character_set_server; // 檢視預設字符集
select @@secure_file_priv;

show variables like ‘character%’;