【MySQL|第九篇】視圖、函數與優化

目錄

十、視圖

1、簡單視圖:

2、復雜視圖:

3、視圖更新:

十一、函數

1、函數創建:

十二、數據庫優化

1、索引優化:

2、查詢優化:

3、設計優化:


十、視圖

????????在 MySQL 中,視圖(View)是一種虛擬的表,它是基于一個或多個表的查詢結果構建而成的。視圖提供了一種方便和靈活的方式來處理復雜查詢、控制數據訪問和重用查詢邏輯。

????????通過使用視圖,可以提高查詢的效率和可維護性,并增強數據庫的安全性。

????????視圖一方面可以幫我們使用表的一部分而不是所有的表,另一方面也可以針對不同的用戶制定不同的查詢視圖。比如,針對一個公司的銷售人員,我們只想給他看部分數據,而某些特殊的數 據,比如采購的價格,則不會提供給他。再比如,人員薪酬是個敏感的字段,那么只給某個級別以上的人員開放,其他人的查詢視圖中則不提供這個字段。

理解視圖:

  • 視圖(view)是一個虛擬表,非真實存在,其本質是根據SQL語句獲取動態的數據集,并為其命名,用戶使用時只需使用視圖名稱即可獲取結果集,并可以將其當作表來使用
  • 數據庫中只存放了視圖的定義,而并沒有存放視圖中的數據(數據存放在原來的表中
  • 使用視圖查詢數據時,數據庫會從原來的表中取出對應的數據。因此,視圖中的數據是依賴于原來的表中的數據的。一旦表中的數據發生改變,顯示在視圖中的數據也會發生改變

視圖優點:

  • 操作簡單
  • 減少數據冗余
  • 數據安全
  • 適應多變的需求
  • 能夠分解復雜的查詢邏輯

視圖分類: 簡單視圖 和 復雜視圖

語法:

CREATE [OR REPLACE] VIEW view_name [(字段列表)]

AS

select語句 [WITH [CASCADED |LOCAL] CHECK OPTION]

select語句 :表示一個完整的查詢語句,將查詢記錄映射到視圖中

[with [cascaded | local] check option]? :可選項,表示更新視圖時要保證在該視圖的權限范圍之內,cascaded表示級聯,local表示只考慮當前視圖。

1、簡單視圖:

????????簡單視圖是基于單個表的查詢結果構建的視圖。它們通常包含簡單的SELECT語句,可以直接從單個表中選擇列或進行簡單的列計算。簡單視圖的查詢邏輯相對較簡單,不涉及復雜的多表連接操作或子查詢。

案例1:基于bemp構建視圖,數據列只有idname

drop table emp;drop table dept;create table dept(id int primary key,name varchar(20));insert into dept values(1,'java'),(2,'bigdata'),(3,'web');create table emp(id int primary key,name varchar(20),salary double,dept_id int,foreign key(dept_id) references dept(id));insert into emp values(1,'lisi',3000,1),(2,'wangwu',3200,1);insert into emp(id,name,salary) values(5,'zhuqi',3500);insert into emp values(3,'zhansan',2800,1),(4,'zhaoliu',900,2);-- 新建或更新視圖create or replace view v_emp(id,username)asselect id,namefrom emp;desc emp;select * from emp;-- 查看視圖結構desc v_emp;select * from v_emp;

案例2:基于bemp員工表構建視圖,要求有編號、名字、薪水和年薪

create view v_emp1asselect id,name,salary,salary*30from emp;

案例3:基于v_emp1構建視圖,只需要名字和薪水

create view v_emp_newasselect name,salary*30 as yearSalfrom v_emp1;select * from v_emp_new;

2、復雜視圖:

????????復雜視圖是基于多個表的連接操作、子查詢或其他復雜查詢邏輯構建的視圖。它們可以涉及多個表之間的關聯、聚合函數、子查詢、條件邏輯等復雜的查詢操作。

案例1:構建視圖v_emp_dept,能查詢員工信息及所屬部門

create view v_emp_deptasselect concat(e.name,'(',d.name,')') as username,e.salary,e.dept_id,d.name dept_namefrom emp e, dept dwhere e.dept_id=d.id;select * from v_emp_dept;

查看當前數據庫下的視圖語法

show tables;

重命名視圖

rename table old_view_name to new_view_name;

修改視圖

alter view view_name

as

select查詢語句

注意事項:可以使用創建視圖替換

刪除視圖

drop view if exists view_name;

3、視圖更新:

????????對于簡單視圖,即只涉及單個表的視圖,可以通過直接對底層表進行更新來間接地更新視圖。例如,如果有一個視圖 my_view ,它是從表 my_table 中選擇的某些列,可以通過更新 my_table 來更新視圖中的數據。

注意事項:對基表(數據表)進行更新改會影響視圖!

案例:基于bemp構建視圖,顯示編號和名字,并對數據修改

create view v_bempasselect id,namefrom emp;insert into v_bemp values(6,'briup');update v_bemp set name='zhaosi' where id=4;select * from v_bemp;select * from emp;

如果是復雜視圖,包含下述結構中的任何一種,那么就不能通過它去更新原來

表中數據:

  • 聚合函數(SUM(), MIN(), MAX(), COUNT()等)
  • select查詢列表有數學表達式
  • DISTINCT
  • UNIONUNION ALL
  • 位于選擇列表中的子查詢
  • GROUP BY
  • HAVING
  • JOIN
  • 常量視圖

案例展示:

執行更新操作:

十一、函數

????????函數是事先經過編譯并存儲在數據庫中的一段sql語句集合,調用函數可以簡化應用開發工作,提高數據處理的效率。

1、函數創建:

mysql8 增加了一個安全選項,需要執行一下代碼才能創建函數

set global log_bin_trust_function_creators=TRUE;

基本格式:

delimiter 自定義符號

create function 函數名(形參列表) returns 返回類型 -- 注意是retruns

begin

????????函數體 -- 若干sql語句,但是不要直接寫查詢

????????return val;

????????end 自定義符號

delimiter ;

-- 格式說明:

delimiter 自定義符號 是為了在函數內寫語句方便,制定除了;之外的符號作為函數書寫結束標志,一般用$$或者//

形參列表:形參名 類型 類型為mysql支持類型

返回類型: 函數返回的數據類型,mysql支持類型即可

函數體:若干sql語句組成

return: 返回指定類型返回值

?案例1:創建無參數的函數

-- 開啟函數創建set global log_bin_trust_function_creators=TRUE;-- 創建無參數的函數delimiter $$create function func01() returns intbeginreturn (select salary from s_emp order by salary desc limit 1);end $$delimiter ;-- delimiter后面必須跟空白字符, 再跟;-- 函數調用select func01();select * from s_emp where salary=func01();

案例2:創建有參數的函數

-- 創建包含參數的函數delimiter $$create function func02(eid int)returns varchar(25)beginreturn (select last_name from s_emp where id=eid);end $$delimiter ;-- 函數調用select func02(1);

設置變量

1)定義用戶變量

固定格式:

-- 定義格式

set @[變量名] = ;

-- 使用格式

@[變量名]

具體案例:

set @eid=10;

select func02(@eid);

2)定義局部變量

????????可以在函數內部定義局部變量。局部變量只在函數內部可見,其作用域僅限于函數內部。

????????局部變量可以使用set賦值。

DECLARE variable_name datatype [DEFAULT initial_value];

-- variable_name 是變量的名稱

-- datatype 是變量的數據類型

-- initial_value 是可選的初始值

具體案例:定義函數獲取商品總價,傳遞數量和單價。

DELIMITER //CREATE FUNCTION get_total_price(num INT, price DECIMAL(10, 2))RETURNS DECIMAL(10, 2)BEGINDECLARE total DECIMAL(10, 2);SET total = num * price;RETURN total;END //DELIMITER ;select get_total_price(5,2.5);-- 刪除函數drop function get_total_price;

十二、數據庫優化

????????數據庫優化是針對關系型數據庫系統的性能和效率進行改進的過程。通過優化數據庫,可以提高查詢速度、減少資源占用,提升系統的響應性和可擴展性。

以下是一些常見的數據庫優化技術和策略:

1、索引優化:

(1)在合適的字段上創建索引

????????如果不加索引的話,那么查找任何哪怕只是一條特定的數據都會進行一次全表掃描,如果一張表的數據量很大而符合條件的結果又很少,那么不加索引會引起致命的性能下降。但是也不是什么情況都非得建索引不可,比如性別可能就只有兩個值,建索引不僅沒什么優勢,還會影響到更新速度,這被稱為過度索引。

????????所以要建在合適的地方,合適的對象上。經常 操作 比較 判斷 的字段應該建索引。索引根據實際需要來設置,不是越多越好,索引本身也是占用內存空間的。

(2)復合索引代替單索引

????????比如有一條語句是這樣的: select * from users where area=’beijing’ and age=22; 如果我們是在areaage上分別創建單個索引的話,由于mysql查詢每次只能使用一個索引,所以雖然這樣已經相對不做索引時全表掃描提高了很多效率,但是如果在areaage兩列上創建復合索引的話將帶來更高的效率。如果我們創建了(area, age,salary)的復合索引,那么其實相當于創建了(area,age,salary)(area,age)(area)三個索引,這被稱為最佳左前綴特性。

????????因此我們在創建復合索引時應該將最常用作限制條件的列放在最左邊,依次遞減。

(3)使用短索引

????????對串列進行索引,如果可能應該指定一個前綴長度。例如,如果有一個CHAR(255)的列,如果在前10 個或20個字符內,多數值是唯一的,那么就不要對整個列進行索引。短索引不僅可以提高查詢速度而且可以節省磁盤空間和I/O操作。

2、查詢優化:

(1)盡量不使用NULL

????????通常,索引字段是不存在 NULL 的,所以指定 IS NULL IS NOT NULL 的話會使得索引無法使用,進而導致查詢性能低下。

(2)減少子查詢

????????執行子查詢時,會創建臨時表,查詢完畢后再刪除它,所以子查詢的速度會收到影響。

(3)減少模糊查詢

????????一般情況下不鼓勵使用like操作,如果非使用不可,如何使用也是一個問題。like "%aaa%" 不會使用索引而 like "aaa%" 可以使用索引。

(4)使用 EXISTS 代替 IN

????????在大多時候,[NOT] IN [NOT] EXISTS 返回的結果是相同的。但是兩者用于子查詢時,EXISTS 的速度會更快一些。

-- exists使用案例-- 參考博文https://blog.csdn.net/zhangzehai2234/article/details/124652056-- exists:外表先進行循環查詢,將查詢結果放入exists的子查詢中進行條件驗證,確定外層查詢數據是否保留-- 查詢存在員工的部門的信息select id,namefrom s_dept as sdwhere exists (select id,last_name,dept_idfrom s_empwhere dept_id = sd.id);-- 查詢已分配好部門員工的信息select id,last_name,dept_idfrom s_emp as sewhere exists(select id,namefrom s_deptwhere id = se.dept_id);

(5)避免排序

????????我們在查詢的時候,雖然我們沒有想要進行排序,但是在數據庫內部頻繁地進行著暗中的排序。因此對于我們來說,了解都有哪些運算會進行排序很有必要,會進行排序的代表性的運算有下面這些

  • group by 子句
  • order by 子句
  • 聚合函數(sumcountavgmaxmin)

????????在極值函數(MAX/MIN)中使用索引,使用這兩個函數時都會進行排序。但是如果參數字段上建有索引,則只需要掃描索引,不需要掃描整張表。

????????能寫在 WHERE 子句里的條件不要寫在 HAVING 子句里。

  • distinct

????????為了排除重復數據,distinct 也會進行排序。如果需要對兩張表的連接結果進行去重,可以考慮使用exists代替distinct,以避免排序。

  • 集合運算符(unionintersectexcept)
  • 窗口函數(rankrow_number)

(6)limit 分頁機制

????????300W數據,select * from tableA limit 1000000,10; 會導致mysql1000000之前的所有數據全部掃描一次,大量浪費了時間。解決辦法:

  • 查詢字段加索引,可以建立與主鍵的復合索引
  • limit最大的問題在于要掃描前面不必要的數據,所以可以先對主鍵的條件做設定,然后記錄住主鍵的位置再取行。 select * from tableA where id > 1000000 order by id limit 10;

(7)增加中間表

????????對于需要經常聯合查詢的表,可以建立中間表以提高查詢效率。通過建立中間表,把需要經常聯合查詢的數據插入到中間表中,然后將原來的聯合查詢改為對中間表的查詢,以此來提高查詢效率。

3、設計優化:

(1)默認值設置不為空

????????只要列中包含有NULL值都將不會被包含在索引中,復合索引中只要有一列含有NULL值,那么這一列對于此復合索引就是無效的。所以我們在數據庫設計時不要讓字段的默認值為NULL

(2)選取最適用的字段屬性

????????MySQL可以很好的支持大數據量的存取,但是一般說來,數據庫中的表越小,在它上面執行的查詢也就會越快。因此,在創建表的時候,為了獲得更好的性能,我們可以將表中字段的寬度設得盡可能小。

????????例如,在定義郵政編碼這個字段時,如果將其設置為CHAR(255),顯然給數據庫增加了不必要的空間,甚至使用VARCHAR這種類型也是多余的,因為CHAR(6)就可以很好的完成任務了。同樣的,如果可以的話,我們應該使用MEDIUMINT而不是BIGIN來定義整型字段。

(3)讀寫分離

????????海量數據的存儲及訪問,通過對數據庫進行讀寫分離,來提升數據的處理能力,數據庫的寫操作都集中到一個數據庫上,而一些讀的操作呢,可以分解到其它數據庫上。

優點:得數據庫的處理壓力分解到多個數據庫上,從而大大提升數據處理能力

缺點:付出數據復制的成本。

(4)數據庫范式化和規范化

????????通過合理的范式設計,減少數據冗余和不一致性;使用適當的關系模型和數據結構,以提高查詢和更新的效率。

(5)分表

????????分表技術比較麻煩,要修改程序代碼里的SQL語句,還要手動去創建其他表,也可以用merge存儲引擎實現分表,相對簡單許多。分表后,程序是對一個總表進行操作,這個總表不存放數據,只有一些分表的關系,以及更新數據的方式,總表會根據不同的查詢,將壓力分到不同的小表上,因此提高并發能力和磁盤I/O性能。

????????分表分為垂直拆分和水平拆分:

????????垂直拆分:把原來的一個很多字段的表拆分多個表,解決表的寬度問題。 你可以把不常用的字段單獨放到一個表中,也可以把大字段獨立放一個表中,或者把關聯密切的字段放一個表中。

????????水平拆分:把原來一個表拆分成多個表,每個表的結構都一樣,解決單表數據量大的問題。

數據庫優化是一個持續的過程,需要結合具體的應用場景和需求進行調整和改進。通過綜合考慮索引、查詢、范式化、緩存、分區、硬件配置等方面的優化策略,可以提升數據庫系統的性能和效率。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/97862.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/97862.shtml
英文地址,請注明出處:http://en.pswp.cn/web/97862.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用Docker和虛擬IP在一臺服務器上靈活部署多個Neo4j實例

使用Docker和虛擬IP在一臺服務器上靈活部署多個Neo4j實例 前言 在現代應用開發中,圖數據庫Neo4j因其強大的關系處理能力而備受青睞。但有時候我們需要在同一臺服務器上運行多個Neo4j實例,比如用于開發測試、多租戶環境或者A/B測試。傳統的端口映射方式…

K8s學習筆記(一):Kubernetes架構-原理-組件

Kubernetes(簡稱 K8s)是一款開源的容器編排平臺,核心目標是實現容器化應用的自動化部署、擴展、故障恢復和運維管理。其設計遵循 “主從架構”(Control Plane Node),組件分工明確,通過 “聲明式…

ensp配置學習筆記 比賽版 vlan 靜態路由 ospf bgp dhcp

學習配置VLAN 虛擬局域網,目的讓兩臺在同一網段的設備,在交換機中訪問。基礎指令:sys 進入系統 sysname R1 修改交換機名字為R1 display cur 查看數據、端口等交換機信息 (在端口中,可以直接display this 可以直接看…

倉頡編程語言青少年基礎教程:enum(枚舉)類型和Option類型

倉頡編程語言青少年基礎教程:enum(枚舉)類型和Option類型enum 和 Option 各自解決一類“語義級”問題:enum 讓“取值只在有限集合內”的約束從注釋變成編譯器強制;Option 讓“值可能不存在”的語義顯式化。enum類型enu…

javaEE-Spring IOCDI

目錄 1、什么是Spring: 2.什么是IoC: 3. 什么是控制反轉呢? 4.IoC容器具備以下優點: 5.DI是什么: 依賴注?方法: 三種注入方法的優缺點: Autowired注解注入存在的問題: Autowired和Resource的區別&#xff…

TensorFlow Lite 全面解析:端側部署方案與PyTorch Mobile深度對比

1 TensorFlow Lite 基礎介紹 TensorFlow Lite (TFLite) 是 Google 為移動設備(Android, iOS)、微控制器(Microcontrollers)和其他嵌入式設備(如 Raspberry Pi)開發的輕量級深度學習推理框架。它的核心目標是…

mapbox進階,使用jsts實現平角緩沖區

????? 主頁: gis分享者 ????? 感謝各位大佬 點贊?? 收藏? 留言?? 加關注?! ????? 收錄于專欄:mapbox 從入門到精通 文章目錄 一、??前言 1.1 ??mapboxgl.Map 地圖對象 1.2 ??mapboxgl.Map style屬性 1.3 ??jsts myBufferOp 緩沖區生成對對象 …

linux裝好顯卡后如何檢查

背景:客戶通知裝好了顯卡,我們去機器上查看一下一. 使用到的命令 watch -n 1 nvidia-smi 可實時查看gpu的使用率nvidia-smi 之查看一次 二、查看內存和顯存 內存使用命令 free -h,顯存使用 nvidia-smi 這只是查看的navidia, 其他品牌的會不一樣

人工智能深度學習——卷積神經網絡(CNN)

一、圖像卷積運算 對圖像矩陣與濾波器矩陣進行對應相乘再求和運算,轉化得到新的矩陣。 作用:快速定位圖像中某些邊緣特征 英文:convolution(CNN)池化層實現維度縮減 池化:按照一個固定規則對圖像矩陣進行處…

SaaS 建站從 0 到 1 教程:Vue 動態域名 + 后端子域名管理 + Nginx 配置

SaaS 建站從 0 到 1 教程:Vue 動態域名 后端子域名管理 Nginx 配置 一、什么是 SaaS 建站? SaaS(Software as a Service)建站,就是通過一套統一的系統,支持用戶在線注冊、綁定域名、快速生成專屬網站。…

關于神經網絡中回歸的概念

神經網絡中的回歸詳解 引言 神經網絡(NeuralNetworks)是一種強大的機器學習模型,可用于分類和回歸任務。本文聚焦于神經網絡中的回歸(Regression),即預測連續輸出值(如房價、溫度)。…

JAVASCRIPT 前端數據庫-V9--仙盟數據庫架構-—仙盟創夢IDE

老版本 在v1 版本中我們講述了 基礎版的應用JAVASCRIPT 前端數據庫-V1--仙盟數據庫架構-—-—仙盟創夢IDE-CSDN博客接下載我們做一個更復雜的的其他場景由于,V1查詢字段必須 id接下來我們修改了了代碼JAVASCRIPT 前端數據庫-V2--仙盟數據庫架構-—-—仙盟創夢IDE-CS…

k8s核心資料基本操作

NamespaceNamespace是kubernetes系統中的一種非常重要資源,它的主要作用是用來實現多套環境的資源隔離或者多租戶的資源隔離。默認情況下,kubernetes集群中的所有的Pod都是可以相互訪問的。但是在實際中,可能不想讓兩個Pod之間進行互相的訪問…

PostgreSQL——分區表

分區表一、分區表的意義二、傳統分區表2.1、繼承表2.2、創建分區表2.3、使用分區表2.4、查詢父表還是子表2.5、constraint_exclusion參數2.6、添加分區2.7、刪除分區2.8、分區表相關查詢2.9、傳統分區表注意事項三、內置分區表3.1、創建分區表3.2、使用分區表3.3、內置分區表原…

Linux任務調度全攻略

Linux下的任務調度分為兩類,系統任務調度和用戶任務調度。系統任務調度:系統周期性所要執行的工作,比如寫緩存數據到硬盤、日志清理等。在/etc目錄下有一個crontab文件,這個就是系統任務調度的配置文件。/etc/crontab文件包括下面…

回溯算法通關秘籍:像打怪一樣刷題

🚀 回溯算法通關秘籍:像打怪一樣刷題! 各位同學,今天咱們聊聊 回溯算法(Backtracking)。它聽起來玄乎,但其實就是 “暴力搜索 剪枝” 的優雅版。 打個比方:回溯就是在迷宮里探險&am…

嵌入式Linux常用命令

📟 核心文件與目錄操作pwd-> 功能: 打印當前工作目錄的絕對路徑。-> 示例: pwd -> 輸出 /home/user/projectls [選項] [目錄]-> 功能: 列出目錄內容。-> 常用選項:-l: 長格式顯示(詳細信息)-a: 顯示所有文件(包括隱…

深入理解 Linux 內核進程管理

在 Linux 系統中,進程是資源分配和調度的基本單位,內核對進程的高效管理直接決定了系統的性能與穩定性。本文將從進程描述符的結構入手,逐步剖析進程的創建、線程實現與進程終結的完整生命周期,帶您深入理解 Linux 內核的進程管理…

ACP(三):讓大模型能夠回答私域知識問題

讓大模型能夠回答私域知識問題 未經過特定訓練答疑機器人,是無法準確回答“我們公司項目管理用什么工具”這類內部問題。根本原因在于,大模型的知識來源于其訓練數據,這些數據通常是公開的互聯網信息,不包含任何特定公司的內部文檔…

使用Xterminal連接Linux服務器

使用Xterminal連接Linux服務器(VMware虛擬機)的步驟如下,前提是虛擬機已獲取IP(如 192.168.31.105)且網絡互通: 一、準備工作(服務器端確認)確保SSH服務已安裝并啟動 Linux服務器需要…