教程-檢視的概念和基本用法

huidaoli發表於2013-08-02

快速入門:使用ecshop 的goods表,查詢平均價格前三高的欄目。

  傳統方式:

  select cat_id,avg(shop_price) as aprice from goods

  group by cat_id

  order by aprice desc limit 3;

  新的方式:利用建立檢視

  #建立檢視:

  create view v1 as

  select cat_id,avg(shop_price) as aprice from goods;

  #檢視檢視:

  Show tables;

  #檢視檢視列:

  Desc 檢視名

  #檢視檢視建立:

  Show create view 檢視名

  #刪除檢視:

  Drop view 檢視名

  檢視的好處:

  1. 簡化查詢。

  2. 許可權控制。

  3. 分表查詢.

  4. 可維護性好。、

  A .簡化查詢,上面的例子用檢視實現的程式碼:

  建立檢視表

  Create view v1 as

  Select gooods_id,cat_id,goods_name,avg(shop_price) as aprice from esc_goods group by cat_id;

  #查詢檢視表

  Select *from v1 order by aprice limit 3;

  B 許可權控制,假設有如下表,由小劉來維護,需要他進行開發和管理銷售軟體,但又不能讓其看到成本價,該怎麼做?

  編號產品名稱市場價成本價單位品牌

  1黃金446200元/克周大福

  2鉑金375.94192元/克周大福

  3金條456.87185.35元/克周大生

  4飾品461203.58元/克周大生

  #演示如何通過檢視來控制許可權

  #建立珠寶表

  create table jewelry(

  id int unsigned not null auto_increment primary key,

  name varchar(20) not null,

  price decimal(10,2) not null,

  cost decimal(10,2) not null,

  unit varchar(20) not null,

  brand varchar(30) not null

  );

  #插入幾條記錄

  insert into jewelry(name,price,cost,unit,brand) values('黃金',446,200,'元/克','周大福');

  insert into jewelry(name,price,cost,unit,brand) values('鉑金',375.94,192,'元/克','周大福');

  insert into jewelry(name,price,cost,unit,brand) values('金條',456.87,185.35,'元/克','周大生');

  insert into jewelry(name,price,cost,unit,brand) values('飾品',461,203.58,'元/克','周大生');

  #建立一個檢視

  #新建使用者,登入MySQL

  mysql> insert into user(host,user,password,ssl_cipher,x509_issuer,x509_subject) values('localhost'

  test',password('123'),'','','');

  #重新整理系統許可權表

  mysql> flush privileges;

  #為使用者授權,要使用root賬戶,針對某個檢視建立許可權(資料庫名.檢視名)

  grant select,insert,update,delete on wcp.vj to test@localhost;

  #刪除使用者

  C 分表查詢,加快查詢速度。假設現在有一個海量資料表,比如QQ賬戶表,使用者反映登入時間太長,有沒有辦法將其優化一下?

  分表:

  可以按qq號碼取餘的方式將qq使用者表分成10張表,

  Qq1,qq2,qq3,qq4,qq5,

  如何查詢?

  10003 %10 = 3

  Create view vq as

  Slect * from qq1 union select * from qq2

  D 維護性好,小明在公司做網站開發和維護工作,因為業務的變化,資料庫中有兩張表a和b,現在需要組合成c表,你能幫他出出主意嗎?

  A表

  B表

  C表

  可以利用檢視,先把表A和表B聯合成一張表C,然後從c表分別建立原來 表A的檢視和表B的檢視 ,這樣程式只需要稍微改下,原來的查詢等語句照樣使用。

  深入理解檢視-檢視的演算法及其與表的關係

  1. 檢視和表是什麼關係?

  檢視是一張虛擬的表,並不是物理上存在的,只不過我們可以將其作為表來使用。

  使用檢視可以節省空間。

  2. 檢視是如何工作的?

  在使用檢視的時候,引用對應的表,查詢得到這個結果。

  3. 檢視和表之間的操作會影響對方嗎?

  編號名稱價格作業系統品牌

  1iphone55999iosApple

  2iphone4s4430iosApple

  3htc 328w2930androidHTC

  4htc G212250androidHTC

  5htc one s2500androidHTC

  6lumia 9204590wp8Nokia

  7lumia 8002900wp7Nokia

  8nokia N9 2300MeeGoNokia

  9Galaxy 33480androidsamsung

  #建立phone表

  create table phone(

  id int unsigned not null auto_increment primary key,

  name varchar(30) not null,

  price decimal(7,2) not null,

  os varchar(30) not null,

  brand varchar(30) not null

  );

  #插入八條記錄

  insert into phone(name,price,os,brand) values('iphone5',5999,'ios','Apple');

  insert into phone(name,price,os,brand) values('iphone4s',4430,'ios','Apple');

  insert into phone(name,price,os,brand) values('htc328w',2930,'android','HTC');

  insert into phone(name,price,os,brand) values('htc G21',2250,'android','HTC');

  insert into phone(name,price,os,brand) values('htc one s',2500,'android','HTC');

  insert into phone(name,price,os,brand) values('lumia920',4590,'wp8','Nokia');

  insert into phone(name,price,os,brand) values('lumia800',2900,'wp7','Nokia');

  insert into phone(name,price,os,brand) values('nokia n9',2300,'meego','Nokia');

  #建立一個檢視vphone1

  mysql> create view vp1 as select name,price,brand from phone;

  #對錶更新,看其對檢視的影響

  結論:表的更新會直接影響到檢視。

  #檢視檢視

  #對檢視更新,看其對錶的影響

  update vp1 set price = price - 500;

  結論:改變檢視是可以改變表的。但是不是總是能改變,只有在檢視和原表一一對應的情況下才能通過檢視改變表。

  #再建立一個檢視,vphone2

  mysql> create view vp2 as

  -> select brand,avg(price) as aprice from phone

  -> group by brand;

  #檢視檢視

  #更新檢視vphone2

  mysql> update vp2 set aprice = aprice + 500;

  ERROR 1288 (HY000): The target table vp2 of the UPDATE is not updatable

  結論:但是不是總是能改變,只有在檢視和原表一一對應的情況下才能通過檢視改變表。

  #向檢視vphone1中插入記錄,

  mysql> insert into vp1 values('galaxy '3470','samsung','android');

  ERROR 1423 (HY000): Field of view 'wcp.vp1' underlying table doesn't have a default value

  對於在檢視中沒有出現的列,而在表中有沒有預設值,則此時插入會失敗。

  #更改表結構

  mysql> alter table phone modify os varchar(30) not null default '';

  #再向檢視vphone1中插入記錄

  mysql> insert into vp1 values('galaxy '3470','samsung','android');

  4. 檢視使用注意事項

  a. 檢視也是一種表,是虛擬表,或者說表和檢視共享資料庫中相同的名稱空間,不能與已有的表(檢視)出現重名。

  b. 檢視屬於資料庫。在預設情況下,將在當前資料庫建立新檢視。

  檢視的演算法

  1. 使用檢視來實現查詢每個欄目下最貴的商品,該怎麼做?

  原先做法:

  mysql> select goods_id,goods_name,cat_id,shop_price from (

  -> select goods_id,goods_name,cat_id,shop_price from goods

  -> order by cat_id,shop_price desc) as temp

  -> group by cat_id;

  使用檢視來實現:

  mysql> create view vec as

  -> select goods_id,goods_name,cat_id,shop_price from goods

  -> order by cat_id,shop_price desc;

  mysql> select * from vec group by cat_id;

  結果不對,why?

  把建立檢視和查詢檢視的語句合併到一起。

  select * from select goods_id,goods_name,cat_id,shop_price from goods group by cat_id order by cat_id,shop_price desc;

  這樣又回到我們錯誤的老路上。

  原因,就是因為使用的是merge演算法,

  檢視的三種演算法(algorithm)

  模式說明備註

  merge合併,在執行檢視的時候,將查詢檢視語句和建立檢視語句合併到一起,然後執行。預設

  temptable臨時表,在執行查詢檢視語句時,首先執行建立檢視語句,並將其作為一個臨時表,接著讓查詢檢視的語句查詢。

  undefined未定義,自動選擇,

  改變檢視的演算法:

  Create algorithm = temptable view 檢視名 as

  mysql> create algorithm=temptable view vec as

  -> select goods_id,goods_name,cat_id,shop_price from goods

  -> order by cat_id,shop_price desc;

相關文章