1. 程式人生 > >Mysql05隔離級別,檢視,索引,事務,左右連線

Mysql05隔離級別,檢視,索引,事務,左右連線

Mysql資料庫day05

 

行內檢視子查詢

l  子查詢在from後面

l  從一個查詢的查詢結果,再查詢

 

select … from (select …) t

 

l  行內檢視後面必須起一個別名

 

Select欄位列表中的子查詢

l  select a,b,c,(select …) from …

 

多表關聯查詢

l  多張表,按條件連線成一張表

 

l  Select 1.欄位列表2.欄位列表

from  1,2

where 1.欄位1=2.欄位2

        

l  自連線:將一張表看作是兩張表進行連線

 

l  標準表連線語法:

select …

from

           

1

inner join 2

           on  連線條件

           inner join 3

           on  連線條件

           inner

join 4

           on  連線條件

 

l  連線

連線條件以外的資料,也查詢出來

n  左外連線

a  left outer join  b  on  …

                   左側a表,條件外的資料也查詢出來

n  右外連線

a  right outer join  b  on  …

右側b表,條件外的資料也查詢出來

 

 

select查詢結構

         select

         distinct

         from

         join  on

         left join on

         right join on

         where

         group by

         having

         order by

         limit

 

事務

l  事務是資料操作的最小單元

l  多個數據增刪改操作,完成的一項業務處理

l  如果事務事務成功,其中每一項操作都生效

        如果事務事務失敗,其中每一項操作都失敗

l  資料庫資料操作,以事務為一個最小操作單元,

        不應該以一個sql語句為一個操作單元;

        要麼整個事務成功,要麼整個事務失敗

l  在當前事務中對資料的修改,只對當前連線可見

 

l  ACID

            A - 原型性 Atomic

            C - 一致性 Consistency

                    轉賬前 a+b = 100

                    轉帳後 a+b = 100

            I - 隔離性 Isolation

                    一個事物進行中時,

                    另一事物不能操作資料

            D - 永續性 Durancy

                    提交事務之後,

                    資料持久生效

 

l  事務操作

 

n  開始事務           

            start transaction; / begin;

       

n  提交事務           

            commit;

       

n  回滾事務

            rollback;

 

隔離級別

l  set tx_isolation='read-uncommitted';

l  set tx_isolation='read-committed';

l  set tx_isolation='repeatable-read';

l  set tx_isolation='serializable';

l  隔離級別越低,效率越高,資料訪問衝突越多

l  隔離級別越高,效率越低,資料訪問衝突越少

l  資料庫預設隔離級別是repeatable-read

資料訪問衝突問題

n  髒讀

讀取到其他事物未提交的資料

 

n  幻讀

一個事務新增或刪除資料並提交,

另一個事務查詢不到新資料,或仍查詢到已刪除的資料

 

n  不可重複讀

再次查詢的資料,與第一次查詢的資料不一致

        

      隔離級別對應資料訪問衝突現象

        

read-uncommitted

髒讀,幻讀,不可重複讀

read-committed

幻讀,不可重複讀

repeatable-read

幻讀

serializable

 

 

 

檢視

l  將一個查詢儲存在資料庫中

l  可以從這個查詢的查詢結果,再查詢

l  作用:

n  簡化查詢

n  安全

可以讓低許可權使用者,只能從檢視查詢,

而不能去碰真實資料表

      建立檢視

                   create  (or replace)  view  v1

                   as

                   select …

      檢視檢視

                   show tables;

                   desc v1;

                   show create table v1\G

      刪除檢視

                   drop view v1;

 

索引

l  提高欄位的過濾查詢速度

l  常見索引資料結構:

n  B-Tree

n  雜湊表

 

建立索引

    create index index_name on tb1(name);

n  where name='abc'

n  where name like 'abc%'

n  order by name

n  where name like '%abc%' 不使用索引

                   create index index_name on tb1(name, birthday);

n  where name='abc' and birthday='xxxxxx'

n  where name='abc'

n  where birthday='xxxx' 第二個欄位單獨過濾不使用索引

           

檢視索引

                   show create table tb1\G

刪除索引

                   alter table tb1 drop index index_name;

練習


1.       只有一個下屬的主管資訊

主管id             手下

100                     3

120                     5

130                     1

160                     1



                   員工id              first_name       salary

                   130                     xxx                      xxx

                   160                     xxx                      xxx

                  

                   select employee_id,first_name,salary

                   from employees where employee_id in

                   (select manager_id from employees

                    where manager_id is not null

group by manager_id having count(*)=1)



2.       平均工資最高的部門編號



過濾條件是用 9000 過濾部門



部門                   平均工資

30                       6000

50                       7000

80                       5000

90                       9000

100                     9000

                   select department_id,round(avg(salary),2) a

                   from employees

where department_id is not null

group by department_id

having a=

                   (select  max(a)  from

                   (select department_id, round(avg(salary),2) a

                   from employees

where department_id is not null

group by department_id) t) -- 必須起別名



3.       平均工資最低的工種,查詢做這些工作的人

工種         平均工資

A                5000

B                9000

C                3000

D                12000

E                3000

Select employee_id,first_name,salary,job_id

From employees

Where job_id in

(select job_id from employees

group by job_id

having round(avg(salary),2)=

(select min(a) from

(select job_id,round(avg(salary),2) a

from employees

group by job_id) t))



4.       查詢員工工資,同時列出最高工資

select

         employee_id,

         first_name,

         salary,

         (select max(salary) from employees) max

From

         Employees;

        

5.       部門表

Select * from departments;



6.       查詢員工資訊,並顯示部門名稱

select  e.employee_id,

            e.first_name,

            e.salary,

            d.department_id,

            d.department_name

from  employees  e,

           departments  d

where       e.department_id=d.department_id;

        

7.       地區表

Select * from locations;



8.       查詢部門,同時顯示部門所在城市

select

         d.department_id,

         d.department_name,

         L.location_id,

         L.city

from

         departments d,locations L

where

         d.location_id=L.location_id;

        

9.       查詢員工,顯示部門名和城市



         select

                    e.employee_id,e.first_name,e.salary,

                    d.department_name,

                    L.city

           from

                    employees e,

departments d,

locations L

                            where

                                     e.department_id=d.department_id  

and

d.location_id=L.location_id;

        

10.   查詢部門,顯示部門經理名

select

           d.department_id,

           d.department_name,

           d.manager_id,

           e.first_name

from

           departments  d,

           employees  e

where

           d.manager_id=e.employee_id;

        

11.   查詢員工,顯示主管名

select

           e1.employee_id,e1.first_name,e1.salary,

           e2.first_name  manager

from

           employees e1,employees e2

where

           e1.manager_id=e2.employee_id;

        

12.   查詢員工,顯示主管名、部門、部門經理名、城市

employees e1

employees e2

departments d

employees e3

locations l



select e1.employee_id,e1.first_name,

      e2.first_name mgr, d.department_name,

      e3.first_name manager,l.city

from  employees  e1

join   employees  e2

on    e1.manager_id=e2.employee_id

join   departments  d

on    e1.department_id=d.department_id

join   employees  e3

on    d.manager_id=e3.employee_id

join   locations l

on    d.location_id=l.location_id;



13.   查詢所有員工,顯示部門名,沒有部門顯示null

select e.employee_id,e.first_name,

     d.department_name

from employees e

left join departments d

on e.department_id=d.department_id;



14.   按城市分組,計算每個城市的員工數量

select

   l.city, count(*) c

from employees e

join departments d

on  e.department_id=d.department_id

join locations l

on  d.location_id=l.location_id

group by l.city

order by c desc;



15.   Seattle 市所有的員工資訊

select

   e.employee_id,e.first_name,e.salary,

           l.city

from employees e

join departments d

on  e.department_id=d.department_id

join locations l

on  d.location_id=l.location_id

where l.city='Seattle';



16.   事務測試

use test;

drop table if exists tb1;

create table tb1(

  id int primary key auto_increment,

  name varchar(20)

回話1

回話2

Use  test

User test

begin;

begin;

Insert into tb1(name)

values('aa');

 

select * from tb1;

select * from tb1;

commit;

 

 

select * from tb1;

 

commit;

 

select * from tb1;

);

 

回話1

回話2

Use test

Use test

begin;

begin;

insert into tb1(name)

values('bb');

 

update tb1

set name='aaaa'

where id=1;

 

 

Select * from tb1;

 

update tb1

set name='aaaaaaaa'

where id=1;

rollback;

 

Select * from tb1;

Select * from tb1;

 

commit;

 

 

17.   隔離級別測試

回話1

回話2

set tx_isolation=

'read-uncommitted';

set tx_isolation=

'read-uncommitted';

rollback;

begin;

rollback;

begin;

Insert into tb1(name)

values('bb');

 

 

Select * from tb1;

Update tb1

set name='a'

where id=1;

 

 

Select * from tb1;

rollback;

 

 

Select * from tb1;

 

 

回話1

回話2

set tx_isolation=

'read-committed'

set tx_isolation=

'read-committed'

rollback;

begin;

rollback;

begin;

Insert into tb1(name)

values('bb');

 

Update tb1 set

name='aaaaaaaaaaaa'

where id=1;

 

 

select * from tb1;

commit;

 

 

select * from tb1;

 

回話1

回話2

set tx_isolation=

'repeatable-read'

set tx_isolation=

'repeatable-read'

rollback;

begin;

rollback;

begin;

insert into tb1(name)

values('cc');

 

update tb1 set

name='bbbbbbbb'

where id=4;

 

 

select * from tb1;

commit;

 

 

select * from tb1;

 

update tb1 set name=concat('*',name);

 

select * from tb1;

 

 

回話1

回話2

set tx_isolation=

'repeatable-read'

set tx_isolation=

'repeatable-read'

rollback;

begin;

rollback;

begin;

 

select * from tb1;

delete from tb1

where id=4;

 

 

select * from tb1;

commit;

 

 

select * from tb1;

 

update  tb1  set

name=concat('#',name);

 

select * from tb1;

 

 

18.   檢視測試

use  hr;

 

create or replace view v1  as

select

         l.city, count(*) c

from employees e

join departments d

on  e.department_id=d.department_id

join locations l

on  d.location_id=l.location_id

group by  l.city;

 

show tables;

desc v1;

show create table v1\G

          

 

select * from v1;

select c from v1;

select * from v1 where c=1;

 

 

 

 

練習

         子查詢:

1.       工資多於工種 IT_PROG 平均工資的員工

select employee_id,first_name,salary

from employees

where salary>(

           select avg(salary) from employees

           where job_id='IT_PROG'

);

 

2.       平均工資最高的工種顯示工作全名

Jobs表儲存工作全名

 

select job_id,job_title from jobs

where job_id in

(

select job_id from employees

group by job_id

having avg(salary)=(

select max(a) from

(select job_id,avg(salary) a from employees

group by job_id) t

)

);

 

3.       每個部門拿最高工資的人

select employee_id,first_name,salary,department_id

from employees

where (department_id,salary) in

(

select department_id,max(salary)

from employees

where department_id is not null

group by department_id

)

 

4.       每年第一個入職的人

 

select employee_id,first_name,salary,hire_date

from employees

where hire_date in

(

select min(hire_date)

from employees

group by extract(year from hire_date)

);

 

5.       平均工資最高的部門編號

 

select department_id,round(avg(salary),2) a

from employees

where department_id is not null

group by department_id

having a =

(

select max(a) from

(select department_id,round(avg(salary),2) a

from employees

where department_id is not null

group by department_id) t

);

 

6.       下屬人數最多的人,查詢其個人資訊

 

select employee_id,first_name,salary

from employees

where employee_id in

(

Select manager_id

From employees

Where manager_id is not null

Group by manager_id

Having count(*)=

(

select max(c) from

(

Select manager_id, count(*) c

From employees

Where manager_id is not null

Group by manager_id

) t

)

)