爺青回:微軟為 Teams 釋出四張懷舊桌布
1sql優化: 即減少sql語句的執行時間,有哪些方法
1 避免在索引列上使用計算,因為這樣會導致索引失效;避免在索引列上使用 IS NULL 和 IS NOT NULL
2 對查詢進行優化,應儘量避免全表掃描,首先可以考慮在where和order by涉及的列上建立索引
3 儘量避免在where的子句中對欄位進行null值判斷,否則引擎就會放棄使用索引,從而進行全表掃描;
儘量避免在where子句中對欄位進行表示式操作,否則引擎就會放棄使用索引,從而進行全表掃描;
儘量避免在where子句中使用!=或<>操作符,否則引擎就會放棄使用索引,從而進行全表掃描;
儘量避免在where子句中使用or來連線條件,否則引擎就會放棄使用索引,從而進行全表掃描。
4 如果數值是連續的,能用between就不要用in
5 任何地方都不要使用 select * from table ,要用具體的欄位代替“*”,只取出需要的欄位
6 模糊搜尋儘量避免使用前置百分號,否則引擎就會放棄使用索引,從而進行全表掃描
7 一個表的索引數最好不要超過6個,因為太多的索引會影響到表的更新速度
8 如果欄位只包含數值資訊,儘量不要設計為字元型別,否則會降低查詢和連線的效能,同時還會增加儲存開銷
9 避免頻繁建立和刪除臨時表,減少系統表資源的消耗
10 儘量使用 varchar/nvarchar 代替 char/nchar ,因為變長欄位的儲存空間小,這樣可以節省儲存空間,同時對於查詢來說,在一個相對較小的欄位內搜尋,效率自然會更高
11 儘量使用表變數來代替臨時表
12 減少表連線,可適當增加冗餘欄位。
13 表連線情況下,把表資料量大的放於最前面,減少查詢行數
14 用EXISTS替代IN、用NOT EXISTS替代NOT IN
select * from table where exists (子查詢)
子查詢有返回結果, 則exists()返回true, 主查詢返回結果
子查詢每有返回結果, 則exists()返回false, 主查詢不返回結果
2 如何建立索引?
查看錶中已有索引: show index from 表名;
主鍵列會自動建立索引
建立索引的語法格式: alter table 表名 add index [索引名](列名, ..)
索引名不指定,預設使用欄位名
刪除索引的語法格式: alter table 表名 drop index 索引名
如果不知道索引名,可以檢視創表sql語句: show create table classes;
聯合索引的好處:減少磁碟空間開銷,因為每建立一個索引,其實就是建立了一個索引檔案,那麼會增加磁碟空間
3 建立索引的原則?
索引查詢是資料庫中重要的記錄查詢方法,要不要進入索引以及在那些欄位上建立索引都要和實際資料庫系統的查詢要求結合來考慮,下面給出實際中的一些通用的原則:
1. 在經常用作過濾器的欄位上建立索引;
2. 在SQL語句中經常進行GROUP BY、ORDER BY的欄位上建立索引;
3. 在不同值較少的欄位上不必要建立索引,如性別欄位;
4. 對於經常存取的列避免建立索引;
5. 用於聯接的列(主健/外健)上建立索引;
6. 在經常存取的多個列上建立複合索引,但要注意複合索引的建立順序要按照使用的頻度來確定;
7. 預設情況下建立的是非簇集索引,但在以下情況下最好考慮簇集索引,如:含有有限數目(不是很少)唯一的列;進行大範圍的查詢;充分的利用索引可以減少表掃描I/0的次數,有效的避免對整表的搜尋。當然合理的索引要建立在對各種查詢的分析和預測中,也取決於DBA的所設計的資料庫結構。
4 oracle 索引建立的若干原則
我們首先要考慮的是資料量,資料量級別的不同,要考慮的問題有很大區別。幾千條記錄建不建索引其實都無所謂了,差個幾豪秒也感覺不出來,但資料量一旦要增長到百萬, 千萬級別,索引的重要性就體現出來了。
沒有索引一個查詢可能要幾個小時甚至幾天才能出來,對資料庫的影響不僅僅是查詢速度的降低, 在io 上的花費和對資料庫連線資源的佔用甚至會拖跨資料庫。那麼怎樣建立索引,建立什麼型別的索引呢,應該按照幾個方面來考慮。
1. 先要了解業務需求,總結出應用會按照哪幾個欄位來進行查詢。例如一個人員查詢系統可能會按照(姓名,身份證件號碼,性別,住址,民族等),當然可能是幾個欄位的組合查詢。
2. 確定了第一步後要估計資料的分佈。相同值有多少,是不是均勻。如姓名欄位就會有大量的重複情況;性別可能只有兩個值(1,2 分別代表男,女),民族會有56 個。
3. 確定索引的型別。選擇性高的欄位建立B- 樹索引最好,如果資料量太大,可考慮把索引分割槽,在併發情況下通常會表現很好。相當於把一棵很大的B樹拆開成了多棵小樹。只有幾個值的欄位如性別並且資料分佈比較均勻,查詢的平均命中率要是非常高就不需要建立索引,否則可以建立點陣圖索引(但會影響併發)。
oracle建立索引原則 :
索引需要平衡query和DML的需要,常用於(子)查詢的表應建立索引;
把索引建到不同的表空間中;
使用統一的extent大小:
五個block的倍數或者tablespace指定的MINIMUM EXTENT的倍數;
建立索引考慮用NOLOGGING引數,重建索引的時候也一樣;
建立索引時INITRANS值應該比相應的table的值高一些;對常用SQL語句的where條件中的列建立唯一索引或組合索引,組合條件查詢中相應的組合索引更有效;
對於組合索引,根據列的唯一值概率,安排索引順序;如果一個列具有很低的資料基數,並且或者可具有空值,不應作為索引列;
如果where語句中不得不對查詢列採用函式查詢,如upper函式,最好建立相應函式索引;對於低基數集的列,幷包含OR等邏輯運算,考慮用Bitmap索引,對於從大量行的表中返回大量的行時也可以考慮Bitmap索引;
避免在有大量併發DML運算的表中使用Bitmap索引
5 索引的優缺點
1 優點
第一,通過建立唯一性索引,可以保證資料庫表中每一行資料的唯一性。
第二,可以大大加快 資料的檢索速度,這也是建立索引的最主要的原因。
第三,可以加速表和表之間的連線,特別是在實現資料的參考完整性方面特別有意義。
第四,在使用分組和排序子句進行資料檢索時,同樣可以顯著減少查詢中分組和排序的時間
第五,通過使用索引,可以在查詢的過程中,使用優化隱藏器,提高系統的效能。
2 缺點
第一,建立索引和維護索引要耗費時間,這種時間隨著資料 量的增加而增加。
第二,索引需要佔物理空間,除了資料表佔資料空間之外,每一個索引還要佔一定的物理空間,如果要建立聚簇索引,那麼需要的空間就會更大。
第三,當對錶中的資料進行增加、刪除和修改的時候,索引也要動態的維護,這樣就降低了資料的維護速度。
6 在哪些列上能建立索引
一般來說,應該在這些列 上建立索引:
在經常需要搜尋的列上,可以加快搜索的速度;
在作為主鍵的列上,強制該列的唯一性和組織表中資料的排列結構;
在經常用在連線的列上,這 些列主要是一些外來鍵,可以加快連線的速度;
在經常需要根據範圍進行搜尋的列上建立索引,因為索引已經排序,其指定的範圍是連續的;
在經常需要排序的列上創 建索引,因為索引已經排序,這樣查詢可以利用索引的排序,加快排序查詢時間;
在經常使用在WHERE子句中的列上面建立索引,加快條件的判斷速度。
7 sql去重
SQL中的三種去重方法
1 distinct
2 group by
3 row_number 視窗函式進行去重, 在支援視窗函式的 sql(如Hive SQL、Oracle等等) 中可以使用
8 內連線和外連線的區別
內連線(自然連線):inner join
只有兩張表相匹配的行才能出現在結果集, 消除笛卡爾積查詢
外連線: outer join
左外連線:左邊為主表,左邊的表顯示全部;右邊為副表,右邊無符號資料時顯示null,不符合的不顯示;
右外連線:右邊為主表,右邊的表顯示全部;左邊為副表,左邊無符號資料時顯示null,不符合的不顯示;
全外連線:左邊為主表,右邊為副表,主表和副表全部顯示,右邊無符號資料時顯示null,左邊無符號資料時顯示null,符合條件的資料會顯示在一行;
交叉連線:cross join
左邊為主表,右邊為副表,顯示的資料為笛卡爾乘積的形式
9 java中如何使用redis
java中利用jedis連線redis
獲取連線: Jedis jedis = new Jedis("localhost", "6376");
10 redis支援的資料型別及各資料型別的使用場景?
string, 簡單的key-value型別,普通的key/ value 儲存都可以歸為此類
1 存放session key
2 簡訊的驗證碼
hash: 即map鍵值對格式的
存放結構化資料,比如使用者資訊
1 使用者資訊比如使用者的暱稱、年齡、性別、積分等,我們需要先序列化後儲存為一個字串的值,在修改時, 就需要反序列化修改某一項的值,再序列化儲存回去。這樣不僅增大了開銷, 也不適用於一些可能併發操作的場合
2 而Redis的Hash結構可以使你像在資料庫中Update一個屬性一樣只修改某一項屬性值
list: List是一個雙向連結串列
1 各種列表,比如twitter的關注列表、粉絲列表等,最新訊息排行、每篇文章的評論等也可以用Redis的list結構來實現
2 訊息佇列,可以利用Lists的PUSH操作,將任務存在Lists中,然後工作執行緒再用POP操作將任務取出執行
set: 是一種無序的集合, 不重複。將重複的元素放入Set會自動去重。
1 某些需要去重的列表
2 可以儲存一些集合性的資料
sortedset: 有序集合
1 存放一個有序的並且不重複的集合列表
2 可以做帶權重的佇列
3 排行榜相關
4 新聞按照使用者投票和時間排序
11 redis如何解決資料過期?
通過更改key過期,可以將某些叢集中的Redis記憶體使用量減少25%,因此Redis 提供了兩種的方式,用於刪除過期的資料
定期刪除
Redis 預設 100ms 隨即抽取部分設定過期時間的 key,過期了就刪除。優點是避免長時間的在掃描過期 key,缺點是有些過期 key 無法被刪除
不掃描全部 key 的原因是,當設定了過期時間的 key 太多的情況下,會很耗時間,O(n) 的時間複雜度。
惰性刪除
如果查詢了某個過期 key,但定期刪除沒有刪除掉,那就將其刪除了。key 沒過期就正常返回。
12 資料庫表的設計注意事項有哪些?
1 資料庫表命名,將業務和基礎表區分,採用駝峰表示法等
2 資料不要物理刪除,應該加一個標誌位,以防使用者後悔時,能夠恢復
3 排序欄位,按照某種型別來排序(sortcode)最好不依賴id排序,這樣方便我們查詢記錄時按照某種方式排序,而不依賴id。
4 資料是否允許刪除和允許編輯,例如管理員不能刪除,這樣我們在查詢資料時就可以根據該欄位標示來決定某條記錄是否可以編輯。而不用固化到程式碼中。
5 增加備註欄位,雖然我們考慮了很多使用者需要輸入資訊的需求,但是無論何時我們都不可能考慮全,因此可以定義一個備註欄位,允許使用者將其它的資訊填寫在這裡。無論表設計的再神奇,那麼還是加一個備註欄位。
6 新增時間,有新增時間可以明確知道記錄什麼時候新增的。
7 修改時間,可以知道記錄什麼時候被修改了,一旦資料出現問題,可以根據修改時間來定位問題。比如某人在這個時間做了哪些事。
13 三大正規化的瞭解?
第一正規化(原子性)
是最基本的正規化。如果資料庫表中的所有欄位值都是不可分解的原子值
第二正規化(完全依賴主鍵)
需要確保資料庫表中每一列都和主鍵相關,而不能只與主鍵的某一部分相關(主要針對聯合主鍵而言)。也就是說在一個數據庫表中,一個表中只能儲存一種資料,不可以把多種資料儲存在同一張資料庫表中。一張表中出現數據重複就可以將其拆分成兩個表
第三正規化(直接依賴主鍵)
需要確保資料表中的每一列資料都和主鍵直接相關,而不能間接相關。
有時為了滿足查詢速度,可以有意識的讓某些表有些冗餘,這是為了提高整個資料庫的效能,所以有些時候,不一定要拘泥於達到第三正規化或bcn 正規化,只要資料庫的設計可以提高整個資料庫的效能,這就是一個合理的資料庫
14 儲存過程的瞭解和使用?
什麼是儲存過程
SQL語句需要先編譯然後執行,而儲存過程(Stored Procedure)是一組為了完成特定功能的SQL語句集,經編譯後儲存在資料庫中,使用者通過指定儲存過程的名字並給定引數(如果該儲存過程帶有引數)來呼叫執行它。
儲存過程是可程式設計的函式,在資料庫中建立並儲存,可以由SQL語句和控制結構組成。
當想要在不同的應用程式或平臺上執行相同的函式,或者封裝特定功能時,儲存過程是非常有用的。
資料庫中的儲存過程可以看做是對程式設計中面向物件方法的模擬,它允許控制資料的訪問方式。
儲存過程的優點:
(1).增強SQL語言的功能和靈活性:儲存過程可以用控制語句編寫,有很強的靈活性,可以完成複雜的判斷和較複雜的運算。
(2).標準組件式程式設計:儲存過程被建立後,可以在程式中被多次呼叫,而不必重新編寫該儲存過程的SQL語句。而且資料庫專業人員可以隨時對儲存過程進行修改,對應用程式原始碼毫無影響。
(3).較快的執行速度:如果某一操作包含大量的Transaction-SQL程式碼或分別被多次執行,那麼儲存過程要比批處理的執行速度快很多。因為儲存過程是預編譯的。在首次執行一個儲存過程時查詢,優化器對其進行分析優化,並且給出最終被儲存在系統表中的執行計劃。而批處理的Transaction-SQL語句在每次執行時都要進行編譯和優化,速度相對要慢一些。
(4).減少網路流量:針對同一個資料庫物件的操作(如查詢、修改),如果這一操作所涉及的Transaction-SQL語句被組織進儲存過程,那麼當在客戶計算機上呼叫該儲存過程時,網路中傳送的只是該呼叫語句,從而大大減少網路流量並降低了網路負載。
(5).作為一種安全機制來充分利用:通過對執行某一儲存過程的許可權進行限制,能夠實現對相應的資料的訪問許可權的限制,避免了非授權使用者對資料的訪問,保證了資料的安全。
15 資料庫如何實現分頁?
1 MySQL實現分頁: 使用limit
2 Oralce實現分頁:
1 Oracle中有個rownum,其含義更加明顯,就是第幾行的意思,這樣我們就可以通過where條件來進行分段查詢了。
select * from t_user where rownum>=2 and rownum<=4
注意:oracle上面的語句查不到資料,應該套一層,如下
select * from (select a.*, rownum rn from t_user a where rownum <= 4) where rn >= 2
2 minus 運算子來實現分頁, 查詢語句為:
select rownum,t.* from T_ACCOUNT t where rownum<=20
minus
select rownum,t.* from T_ACCOUNT t where rownum<=10
3 sqlserver: 在分頁查詢上,SQL Server比較費勁,沒有一個專門的分頁的語句,靠的是一種巧妙的方法實現分頁查
select * from t_user select * from (select top 2 * from (select top 6 * from t_user order by id asc ) as aaa order by id desc) as bbb order by id asc
16 百萬級量的資料分頁查詢如何優化?
mysql: select * from news where id>=(select id from news limit 490000,1) limit 10;
limit只有一個引數, 預設查詢第1頁, limit後跟的是每頁記錄數
17 資料庫的樂觀鎖和悲觀鎖的理解和使用?
1 理解
1、悲觀鎖,就是對資料的衝突採取一種悲觀的態度,也就是說假設資料肯定會衝突,所以在資料開始讀取的時候就把資料鎖定住。【資料鎖定:資料將暫時不會得到修改】
悲觀鎖是讀取的時候為後面的更新加鎖,之後再來的讀操作都會等待。這種是資料庫鎖
悲觀鎖是資料庫實現,他阻止一切資料庫操作
2、樂觀鎖,認為資料一般情況下不會造成衝突,所以在資料進行提交更新的時候,才會正式對資料的衝突與否進行檢測,如果發現衝突了,則讓使用者返回錯誤的資訊。讓使用者決定如何去做
樂觀鎖是一種思想,具體實現是,表中有一個版本欄位,第一次讀的時候,獲取到這個欄位。處理完業務邏輯開始更新的時候,
需要再次檢視該欄位的值是否和第一次的一樣。如果一樣更新,反之拒絕
之所以叫樂觀,因為這個模式沒有從資料庫加鎖
樂觀鎖優點程式實現,不會存在死鎖等問題。他的適用場景也相對樂觀。阻止不了除了程式之外的資料庫操作。
2 使用
1 ORM框架中悲觀鎖樂觀鎖的應用
2 悲觀鎖
select... for update
3 樂觀鎖
- 1 樂觀鎖使用的是版本號
- 1 修改資料之前先查詢資料對應的版本號
- 2 一個執行緒修改時先檢查資料庫中的版本號和自己拿到的版本號是否一致
- 3 修改完畢後把版本號加1
- 2 樂觀鎖不能防止其他執行緒修改資料
18 資料庫中日期和字串的相互轉換?
1 Oracle
時間轉字串 to_char(date,format): select to_char(sysdata,'YYYY"年"MM"月"DD"日"') 時間轉字串 from dual
字串轉時間 to_date(str,format): select to_date('2019-10-25 17:15:20','yyyy-MM-dd HH24:mi:ss') 字串轉時間 from dual
2 MySQL
時間轉字串DATE_FORMAT(): select DATE_FORMAT(SYSDATE(),'%Y年%m月%d日') MySQL日期轉字串 from DUAL;
字串轉時間str_to_date(): select str_to_date('2019-10-25 15:43:28','%Y-%m-%d %H:%i:%s');
H大寫是指的是:24小時制;h小寫是指的是12小時制;
19 union和unionAll區別?
UNION 並集,表中的所有資料,並且去除重複資料(工作中主要用到的是這個);
1 UNION 操作符用於合併兩個或多個 SELECT 語句的結果集
2 需要滿足以下條件:
- 1、相同數量的列;
- 2、列也必須擁有相似的資料型別;
- 3、同時,每條 SELECT 語句中的列的順序必須相同。
3 union去重, 對結果排序
UNION ALL,表中的資料都羅列出來,不去重, 結果不排序
20 mysql的儲存引擎有哪些?
MyISAM儲存引擎: 非事務處理儲存引擎
innoDB儲存引擎: 具備外來鍵支援功能的事務處理引擎
MEMORY儲存引擎: 置於記憶體的表
ARCHIVE儲存引擎: 用於資料存檔的引擎, 資料被插入後就不能再修改了
21 事務的隔離級別有哪些?
Read uncommitted (讀未提交):最低級別,任何情況都無法保證。
Read committed (讀已提交):可避免髒讀的發生。
Repeatable read (可重複讀):可避免髒讀、不可重複讀的發生。
Serializable (序列化):可避免髒讀、不可重複讀、幻讀的發生。
22 mysql和oracle預設的隔離級別是什麼?
mysql預設的事務處理級別是'REPEATABLE-READ(repeatable read)',也就是可重複讀
oracle資料庫支援READ COMMITTED 和 SERIALIZABLE這兩種事務隔離級別。
預設系統事務隔離級別是READ COMMITTED,也就是讀已提交
23 sql如何行轉列和列轉行?
1 行轉列
1 行轉列一般通過CASE WHEN 語句來實現
2 也可以通過 SQL SERVER 2005 新增的運算子PIVOT來實現。
用傳統的方法,比較好理解。層次清晰,而且比較習慣。
但是PIVOT 、UNPIVOT提供的語法比一系列複雜的SELECT…CASE 語句中所指定的語法更簡單、更具可讀性
3 主要思路是分組後使用case進行條件判斷處理
2 列轉行
主要思路也是分組後使用case,也可以用union運算子
select 'a' as 'q'; 這個語句執行後可以把'a'作為列'q'中的值
24 如何檢視sql的執行計劃?
MySQL使用 explain 關鍵字來檢視SQL的執行計劃
25 oracle中的分析函式有哪些?
row_number()可以通過over 根據某欄位排序完之後進行組內(如果有partition by)排序。
rank()是排名的函式,該函式組內排序後會進行跳號,分數相同的作為並列。
dense_rank()該函式不會跳號,分數相同為並列第一,下一個是第二
26 資料庫中除了聚合函式之外還有哪些常用的函式?
常用函式
1 時間函式
獲取當前系統時間select now();
獲取系統的時分秒select curtime();
獲取系統的年月日select curdate();
2 數學函式
向上取捨select ceil(數值);
向下取捨select floor(數值);
獲取四位小數select ceil(rand()*10000);
隨機數select rand();//0~1之間的隨機數;
27 oracle資料庫merge()函式的作用和使用?
通常我們對資料庫資料進行插入的時候,會判斷資料是否已經存在,如果存在就修改,不存在就插入,一般我們會寫兩個sql,一個insert一個update,那麼其實oracle中存在merge函式,可以一次性解決這個問題
作用: 能夠在一個SQL語句中對一個表同時執行inserts和updates操作. MERGE命令從一個或多個數據源中選擇行來updating或inserting到一個或多個表
使用: 比如向資料庫插入一條資料 如果ID和name都相同 就更新AGE的資料,否則就插入
28 sql 中 drop, truncate, delete 的區別?
相同點:drop、delete、truncate 都是刪除表的內容。
不同點:
drop:刪除表內容和結構,釋放空間,沒有備份表之前要慎用;
truncate:刪除表的內容,表的結構存在,可以釋放空間,沒有備份表之前要慎用
delete:刪除表的內容,表的結構還存在,不釋放空間,可以回滾恢復;
drop:drop test 刪除表test,並釋放空間,將test刪除的一乾二淨
truncate:truncate test 刪除表test裡的內容,並釋放空間,但不刪除表的定義,表的結構還在,且truncate刪除資料不能只刪除一行, 只能刪除整張表的資料
delete:
(1)刪除制定資料:刪除表test中年齡等於30且國家為US的資料:delete from test where age=30 and country =‘US’;
(2)刪除整個表:僅刪除表test內的所有內容,保留表的定義,不釋放空間:delete from test 或delete *from test
在都刪除整張表的情況下:drop > truncate > delete
truncate table 速度更快,佔用的日誌更少,這是因為 TRUNCATE TABLE 直接釋放資料頁並且在事務日誌中也只記錄資料頁的釋放
而 DELETE 是一行一行地刪除,在事務日誌中要記錄每一條記錄的刪除
sql語句的不同
drop table table_name;
truncate table_name;
delete from table_name;
29 mysql如何忽略表名的大小寫?
linux下mysql預設是要區分表名大小寫的
mysql是否區分大小寫設定是由引數lower_case_table_names決定的
操作:找到你mysql的配置檔案my.ini(linux下是my.cnf),開啟後找到“[mysqld]”節點,在下面加上一句話
1)lower_case_table_names = 0 (預設)
區分大小寫(即對大小寫不敏感),預設是這種設定。這樣設定後,在mysql裡建立的表名帶不帶大寫字母都沒有影響,都可以正常讀出和被引用。
2)lower_case_table_names = 1
不區分大小寫(即對大小寫敏感)。這樣設定後,表名在硬碟上以小寫儲存,MySQL將所有表名轉換為小寫儲存和查詢表上。該行為也適合資料庫名和表的別名。也就是說,mysql設定為不分割槽大小寫後,建立庫或表時,不管建立時使用大寫字母,建立成功後,都是強制以小寫儲存!
MySQL在Linux下資料庫名、表名、列名、別名大小寫規則是這樣的:
1)資料庫名與表名是嚴格區分大小寫的;
2)表的別名是嚴格區分大小寫的;
3)列名與列的別名在所有的情況下均是忽略大小寫的;
4)變數名也是嚴格區分大小寫的;
5)MySQL在Windows下都不區分大小寫,但是在Linux下預設是區分大小寫的。
6)如果想在查詢時區分欄位值的大小寫,則欄位值需要設定BINARY屬性,設定的方法有多種:
a)建立時設定:CREATE TABLE T(A VARCHAR(10) BINARY);
b)使用alter修改
所以在不同作業系統中為了能使程式和資料庫都能正常執行,最好的辦法是在設計表的時候都轉為小寫!!
30 having和where的區別?
“Where”是一個約束宣告,在查詢資料庫的結果返回之前對資料庫中的查詢條件進行約束,即在結果返回之前起作用,且where後面不能使用“聚合函式”;
where後面之所以不能使用聚合函式是因為where的執行順序在聚合函式之前
“Having”是一個過濾宣告,所謂過濾是在查詢資料庫的結果返回之後進行過濾,即在結果返回之後起作用,並且having後面可以使用“聚合函式”。
having既然是對查出來的結果進行過濾,那麼就不能對沒有查出來的值使用having
聚合函式是比較where和having的關鍵
31 遊標的作用和使用
1 作用: 用來儲存查詢結果集的
2 使用: 遍歷遊標中的資料, 相當於有一個指標指向遊標中的第一行資料,每獲取一行記錄,指標向下移一行
3 語法格式
1 宣告遊標
- 1 格式:declare cursor_name cursor for select_statement
- 2 格式介紹
- 1 cursor_name:遊標名稱,儲存sql語句執行的結果
- 2 select_statement:sql語句
2 開啟遊標
- 格式:open cursor_name;
3 遍歷遊標中的資料
- 1 介紹:相當於有一個指標指向遊標中的第一行資料,每獲取一行記錄,指標向下移一行
- 2 格式
- fetch cursor_name into var_name [, var_name] ...
- 3 格式介紹
- 1 一行fetch只能獲取遊標中的一行記錄,並把記錄中每一列的值賦值給var_name
- 2 一個var_name儲存一行記錄中一個列的值,若有多個列,需要多個變數
- 3 要輸出遊標中的所有資料,需要使用迴圈語句
4 關閉遊標
- 格式:close cursor_name;
32 如何使用資料庫中的定時器, 觸發器, 定時任務?
定時器
自 MySQL5.1.6起,增加了一個非常有特色的功能–事件排程器(Event Scheduler),可以用做定時執行某些特定任務(例如:刪除記錄、對資料進行彙總等等),來取代原先只能由作業系統的計劃任務來執行的工作
更值得 一提的是MySQL的事件排程器可以精確到每秒鐘執行一個任務,而作業系統的計劃任務(如:Linux下的CRON或Windows下的任務計劃)只能精 確到每分鐘執行一次
可將一些資料庫操作定時任務,從程式中挪到資料庫中進行操作,可大大提升執行效率
觸發器
觸發器是mysql5新增的功能,觸發器和儲存過程一樣,都是嵌入到mysql的一段程式。(備註如果after觸發器執行失敗事務會回滾)
定時任務
mysql怎麼讓一個儲存過程定時執行
檢視event是否開啟: show variables like '%sche%'; 或者 SHOW VARIABLES LIKE 'event_scheduler';
OFF表示關閉。那麼,可以使用 sql去開啟事件執行
SET GLOBAL event_scheduler = ON;
到此就可以定時執行執行的過程。
將事件計劃開啟: set global event_scheduler=1;
關閉事件任務: alter event e_test ON COMPLETION PRESERVE DISABLE;
開戶事件任務: alter event e_test ON COMPLETION PRESERVE ENABLE;
33 oracle中如何實現遞迴查詢?
1 oracle中的遞迴查詢採用的語法為 start with 。。。 connect by ..... = prior ....
2 sql語句
SELECT * FROM tree START WITH id = 2 CONNECT BY PRIOR pid = id -- 遞迴查詢父節點
union
SELECT * FROM tree START WITH id = 2 CONNECT BY pid = PRIOR id; -- 遞迴查詢子節點
34 高併發下如何保證修改資料安全?
Mysql中的有兩種方法:
select…for update或lock in share mode
Select...for update的實現方式: set autocommit =0;//關閉自動提交 begin;//開始事務 select * from order where id=989879 for update;//查詢資訊 update order set name='names';//修改資訊 commit;//提交事務 執行select…for update時,一般的SELECT查詢則不受影響。
Lock in share mode的是實現方式: set autocommit =0;//關閉自動提交 begin;//開始事務 select * from order where id=989879 lock in share mode;//鎖定查詢的欄位 update order set name='names';//修改資訊 commit;//提交事務
lock in share mode或select…for update是在事務內起作用的,涉及行鎖的概念。能保證當前session事務鎖定的行不被其他session所修改。
前者屬於共享鎖,允許其他事務新增共享鎖,不允許其他事務修改或者加排它鎖。後者屬於排它鎖,不允許其他事務新增共享鎖和排它鎖,也不允許修改。
一般情況下推薦使用select…for update。使用lock in share mode時需要注意死鎖的問題,就是如果兩個session同時對一行加鎖,那麼將無法執行修改,必須等一個session退出以後才能執行。
如果有兩個session加鎖後同時修改一行,那麼將有一個session被引擎強制關閉並重啟,這樣另一個session的修改就可以順利執行
如果只有一個session修改,另一個session不做修改動作,那麼這個嘗試修改的session將會一直等待鎖被釋放才能繼續執行。
樂觀鎖: 版本號
悲觀鎖: for update
35 oracle中如何實現主鍵自增?
1 oracle中沒有自增欄位,可通過序列+觸發器間接實現
2 實現
1 建立資料表
2 建立自動增長序列create sequence seq_tb_user
minvalue 1
nomaxvalue
start with 1
increment by 1
nocycle --一直累加,不迴圈
--nocache; --不快取
cache 10; --快取10條3 建立觸發器
CREATE OR REPLACE TRIGGER tr_tb_user
BEFORE INSERT ON tb_user FOR EACH ROW WHEN (new.id is null)
begin
select seq_tb_user.nextval into:new.id from dual;
end;4 提交
36 delete誤刪資料沒有備份怎麼恢復?
1 mysql可以通過日誌記錄進行恢復
1 將日誌記錄中的sql語句重新執行一次
2 找到mysql的data目錄下的mysql-bin.00000X檔案,類似這種的,應該有很多個,因為配置時候檔名可以配,所以不保證一定是這樣的,要是不一樣應該也很好找,就是有一組有規律XXXX.00000X檔案就是了。
3 將日誌檔案匯出成sql檔案,方法是在命令列視窗下(其實就是cmd視窗)呼叫mysql的bin目錄mysqlbinlog程式
mysqlbinlog --start-date="2013-10-01 00:00:00" --stop-date="2013-12-12 12:00:00" E:\mysql-5.5.21-win32\data\mysql-bin.000067 > e:\67.sql
2 可以使用資料庫閃回
37 oracle死鎖如何處理?
1 一般情況下,只要將產生Oracle死鎖的語句提交就可以了,但是在實際的執行過程中。使用者可能不知道產生死鎖的語句是哪一句。可以將程式關閉並重新啟動就可以了
2 查詢Oracle死鎖的程序:kill掉這個Oracle死鎖的程序
3檢視資料庫中那些使用者產生了鎖,殺掉ORACLE程序,查詢並殺死死鎖的程序