您好,登錄后才能下訂單哦!
本文實例講述了mysql視圖之創建視圖(CREATE VIEW)和使用限制。分享給大家供大家參考,具體如下:
mysql5.x 版本之后支持數據庫視圖,在mysql中,視圖的幾乎特征符合SQL:2003標準。 mysql以兩種方式處理對視圖的查詢:
mysql支持版本系統的視圖,當每次視圖被更改或替換時,視圖的副本將在駐留在特定數據庫文件夾的arc(archive)文件夾中備份。備份文件的名稱為view_name.frm-00001。如果再次更改視圖,mysql將創建一個名為view_name.frm-00002的新備份文件。mysql允許基于其他視圖創建視圖,就是在視圖定義的select語句中,可以引用另一個視圖。
好啦,多的咱就不贅述了,接下來咱們嘗試使用CREATE VIEW語句創建視圖,先來看下語法結構:
CREATE [ALGORITHM = {MERGE | TEMPTABLE | UNDEFINED}] VIEW [database_name].[view_name] AS [SELECT statement]
然后我們來詳細看下上面的sql中的各種詞是什么意思。首先,第一個中括號里代表的就是創建視圖是的算法屬性,它允許我們控制mysql在創建視圖時使用的機制,并且mysql提供了三種算法:MERGE,TEMPTABLE和UNDEFINED。我們來分別看下:
然后就是view后面的詞組了,它就是名稱的意思,在數據庫中,視圖和表共享相同的命名空間,因此視圖和表不能具有相同的名稱。 另外,視圖的名稱必須遵循表的命名規則。
最后就是SELECT語句了。在SELECT語句中,可以從數據庫中存在的任何表或視圖查詢數據,同時SELECT語句必須遵循以下幾個規則:
在這里我們得稍稍注意下,SELECT語句不需要引用任何表。完事呢,我們來嘗試基于orderDetails表來創建一個表示每個訂單的總銷售額的視圖:
CREATE VIEW SalePerOrder AS SELECT orderNumber, SUM(quantityOrdered * priceEach) total FROM orderDetails GROUP by orderNumber ORDER BY total DESC;
我們如果使用SHOW TABLES命令來查看示例數據庫(yiibaidb)中的所有表,還會看到SalesPerOrder視圖也顯示在表的列表中:
mysql> SHOW TABLES; +--------------------+ | Tables_in_yiibaidb | +--------------------+ | article_tags | | contacts | | customers | | departments | | employees | | offices | | offices_bk | | offices_usa | | orderdetails | | orders | | payments | | productlines | | products | | saleperorder | +--------------------+ 14 rows in set
這是因為視圖和表共享相同的命名空間。要知道哪個對象是視圖或表,就得使用SHOW FULL TABLES命令,如下所示:
mysql> SHOW FULL TABLES; +--------------------+------------+ | Tables_in_yiibaidb | Table_type | +--------------------+------------+ | article_tags | BASE TABLE | | contacts | BASE TABLE | | customers | BASE TABLE | | departments | BASE TABLE | | employees | BASE TABLE | | offices | BASE TABLE | | offices_bk | BASE TABLE | | offices_usa | BASE TABLE | | orderdetails | BASE TABLE | | orders | BASE TABLE | | payments | BASE TABLE | | productlines | BASE TABLE | | products | BASE TABLE | | saleperorder | VIEW | +--------------------+------------+ 14 rows in set
結果集中的table_type列指定哪個對象是視圖,哪個對象是一個表(基表)。如上所示,saleperorder對應table_type列的值為:VIEW。然而,如果要查詢每個銷售訂單的總銷售額,只需要對SalePerOrder視圖執行一個簡單的SELECT語句,如下所示:
SELECT * FROM salePerOrder;
執行上面查詢語句,得到以下結果:
+-------------+----------+ | orderNumber | total | +-------------+----------+ | 10165 | 67392.85 | | 10287 | 61402.00 | | 10310 | 61234.67 | | 10212 | 59830.55 | |-- 此處省略了many many數據-- | | 10116 | 1627.56 | | 10158 | 1491.38 | | 10144 | 1128.20 | | 10408 | 615.45 | +-------------+----------+ 327 rows in set
我們再來基于另一個視圖創建一個視圖,比如,根據SalesPerOrder視圖創建名為大銷售訂單(BigSalesOrder)的視圖,以顯示總計大于60,000的每個銷售訂單,如下所示:
CREATE VIEW BigSalesOrder AS SELECT orderNumber, ROUND(total,2) as total FROM saleperorder WHERE total > 60000;
現在,我們可以從BigSalesOrder視圖查詢數據,如下所示:
SELECT orderNumber, total FROM BigSalesOrder;
執行上面查詢語句,得到以下結果:
+-------------+----------+ | orderNumber | total | +-------------+----------+ | 10165 | 67392.85 | | 10287 | 61402.00 | | 10310 | 61234.67 | +-------------+----------+ 3 rows in set
完事我們再來嘗試使用inner join創建包含客戶編號和客戶支付的總金額的視圖,如下所示:
CREATE VIEW customerOrders AS SELECT c.customerNumber, p.amount FROM customers c INNER JOIN payments p ON p.customerNumber = c.customerNumber GROUP BY c.customerNumber ORDER BY p.amount DESC;
我們使用下面的sql來查詢customerOrders視圖中的數據:
+----------------+-----------+ | customerNumber | amount | +----------------+-----------+ | 124 | 101244.59 | | 321 | 85559.12 | | 239 | 80375.24 | | **** 此處省略了many many數據 ***| | 219 | 3452.75 | | 216 | 3101.4 | | 161 | 2434.25 | | 172 | 1960.8 | +----------------+-----------+ 98 rows in set
再來嘗試使用子查詢創建包含價格高于所有產品的平均價格的產品的視圖,如下所示:
CREATE VIEW aboveAvgProducts AS SELECT productCode, productName, buyPrice FROM products WHERE buyPrice > (SELECT AVG(buyPrice) FROM products) ORDER BY buyPrice DESC;
我們來查詢aboveAvgProducts視圖的數據:
SELECT * FROM aboveAvgProducts;
執行上面查詢語句,得到以下結果:
+-------------+-----------------------------------------+----------+ | productCode | productName | buyPrice | +-------------+-----------------------------------------+----------+ | S10_4962 | 1962 LanciaA Delta 16V | 103.42 | | S18_2238 | 1998 Chrysler Plymouth Prowler | 101.51 | | S10_1949 | 1952 Alpine Renault 1300 | 98.58 | |************* 此處省略了many many數據 *********************************| | S18_3320 | 1917 Maxwell Touring Car | 57.54 | | S24_4258 | 1936 Chrysler Airflow | 57.46 | | S18_3233 | 1985 Toyota Supra | 57.01 | | S18_2870 | 1999 Indy 500 Monte Carlo SS | 56.76 | | S32_4485 | 1974 Ducati 350 Mk3 Desmo | 56.13 | | S12_4473 | 1957 Chevy Pickup | 55.7 | | S700_3167 | F/A 18 Hornet 1/72 | 54.4 | +-------------+-----------------------------------------+----------+ 54 rows in set
好啦,到這里了,視圖的創建和使用已經介紹的差不多了。但是,視圖就沒有什么使用的限制么?答案當然是有的,我們來分別看下。
首先,我們不能在視圖上創建索引,再來就是當使用合并算法的視圖查詢數據時,mysql會使用底層表的索引,還有就是對于使用誘惑算法的視圖,當我們針對視圖查詢數據時,不會使用索引。
還有就是要注意在mysql5.7.7之前版本,是不能在SELECT語句的FROM子句中使用子查詢來定義視圖的。
再來就是如果刪除或重命名視圖所基于的表,則mysql不會發出任何錯誤。但是,mysql會使視圖無效,我們可以使用CHECK TABLE語句來檢查視圖是否有效。
一個簡單的視圖可以更新表中數據,但是基于具有連接,子查詢等的復雜select語句創建的視圖無法更新。
mysql不像Oracle、PostgreSQL等其他數據庫系統那樣支持物理視圖,mysql是不支持物理視圖的。
好啦,關于視圖本次就記錄到這里了。
更多關于MySQL相關內容感興趣的讀者可查看本站專題:《MySQL查詢技巧大全》、《MySQL事務操作技巧匯總》、《MySQL存儲過程技巧大全》、《MySQL數據庫鎖相關技巧匯總》及《MySQL常用函數大匯總》
希望本文所述對大家MySQL數據庫計有所幫助。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。