1. 程式人生 > >MySQl數據庫簡單命令之dcl

MySQl數據庫簡單命令之dcl

問題: ESS 分類 不能 ado lec dff ... ria

SQL (結構化 Structured 查詢 Query 語言 Language)
分類
DDL(數據定義語言) 表的定義、用戶的定義... create drop alter
DML(數據操控語言) 對數據的增加、修改、刪除、查詢 insert update delete select
DCL(數據控制語言) grant(授權) revoke(回收)

DML

    insert into 表 (列...) values (值...);
    insert into 表 (列...) values (值...), (值...)...
    insert into 表1 (列...) select 列... from 表2
    update 表 set 列=新值, ...
    update 表 set 列=新值, ... where 條件
    delete from 表;
    delete from 表 where 條件
    select 列... from 表 
                inner|left join 表 on 連接條件
                where 條件
                group by 列... having 條件
                order by 列 asc|desc
                limit n, m

子查詢 (sub query)

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

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

情況1:把子查詢當做一個值

分解問題:

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

技術分享圖片

情況2:把子查詢當做一張表

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

第一步:按部門分組
(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 條件1 then 結果1
   when 條件2 then 結果2
   ...
   else 結果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 tuser;

技術分享圖片

如果不給權限,只能進行登陸,不能進行其他操作,例如查詢,插入.
例:
技術分享圖片
回收權限

revoke 權限 from 用戶名;

例如:回收之前分配的權限:
revoke select on test.* from tuser;

事務和鎖

事務

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

兩個人同時操作一張表的同一條數據

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

建設銀行賬戶
id        name       balance(余額)
2         張三       3000

```java邏輯
張三轉賬
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 (事務控制語言)

## 鎖(了解)
```sql
客戶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 * from 表 lock in share mode;  添加共享鎖-別人可以再加共享鎖,但不能再加排他鎖

查詢時加排他鎖

select * from 表 for 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%‘;

MySQl數據庫簡單命令之dcl