數據庫常見面試題解析

文章目錄


數據庫的分類及常用的數據庫

數據庫分爲:關係型數據庫和非關係型數據庫

  • 關係型:mysql oracle sqlserver等
  • 非關係型:redis,memcache,mogodb,hadoop等

關係型數據庫

mysql:索引 .索引優化,鎖
數據庫索引

Mysql選用B+樹這種數據結構作爲索引,可以提高查詢索引時的磁盤IO效率,並且可以提高範圍查詢的效率,並且B+樹裏的元素也是有序的。

簡單介紹一下關係數據庫三範式?

範式就是規範,就是關係型數據庫在設計表時,要遵循的三個規範。
要想滿足第二範式必須先滿足第一範式,要滿足第三範式必須先滿足第二範式。

  • 第一範式(1NF)列數據的不可分割(原子性)
  • 二範式(2NF)主鍵
  • 第三範式: 要求一個數據庫表中不包含已在其它表中的非主關鍵字信息。(外鍵)
  • 反三範式,有的時候爲了效率,可以設置重複或者可以推導出的字段.
    訂單(總價)和訂單項(單價)

事務四個基本特徵或 ACID 特性。

事務是併發控制的單位,是用戶定義的一個操作序列。這些操作要麼都做,要麼都不做,是一個不可分割的工作單位。

原子性Atomic 事務內操作不可分割要麼…要麼…
一致性Consistency 數據的完整性必須保持一致(轉賬)後面失敗了要對前面的操作進行回滾
隔離性 Isolation 一個事務開始,其他事務無法干擾
持久性 Durability 事務開始 不能終止

InnoDB對事務的實現方式

利用回滾日誌(undo log) 和 重做日誌(redo log) 兩種表實現事務,並實現 MVCC (多版本併發控制);
查詢需要對資源加共享鎖(S),數據修改需要對資源加排他鎖(X)

利用undo log使讀寫不阻塞,實現了可重複讀。當一個事務正在對一條數據進行修改時,該資源會被加上排它鎖。在事務未提交時對加鎖資源進行讀操作時,讀操作無法讀到被鎖資源,通過一些特殊的標誌符去讀undo log 中的數據(過程很複雜),這樣讀到的都是事務執行之前的數據。

mysql數據庫的默認的最大連接數?

my.ini
在這裏插入圖片描述

說一下msyql的分頁?Oracle的分頁?

爲什麼需要分頁?在很多數據是,不可能完全顯示數據。進行分段顯示.
Mysql是使用關鍵字limit來進行分頁的 limit offset,size 表示從多少索引去多少位.

String sql = 
	"select * from students order by id limit " + pageSize[每頁顯示]*(pageNumber-1)[多少頁] + "," + pageSize;

Oracle的分頁,要使用三層嵌套查詢(百度)。

String sql = 
	 "select * from " +  
	 (select *,rownum rid from (select * from students order by postime desc) where rid<=" + pagesize*pagenumber + ") as t" + 
	 "where t>" + pageSize*(pageNumber-1);

簡單講一下數據庫的觸發器的使用場景?

簡單講一下數據庫的存儲過程的使用場景?

用jdbc怎麼調用存儲過程?

加載驅動
獲取連接
設置參數
執行
釋放連接

常用SQL

簡單說一下你對jdbc的理解?

Java database connection
Java只定義接口,讓數據庫廠商自己實現接口,對於我們者而言。只需要導入對應廠商開發的實現即可。然後以接口方式進行調用.(mysql + mysql驅動(實現)+jdbc)

寫一個簡單的jdbc的程序。寫一個訪問oracle數據的jdbc程序?

加載驅動(com.mysql.jdbc.Driver,oracle.jdbc.driver.OracleDriver)
獲取連接(DriverManager.getConnection(url,usernam,passord))
設置參數  Statement PreparedStatement 
           cstmt.setXXX(index, value);
執行   executeQuery executeUpdate
釋放連接(是否連接要從小到大,必須放到finnaly)

JDBC中的PreparedStatement相比Statement的好處

1:PreparedStatement是預編譯的,比Statement速度快
2:代碼的可讀性和可維護性
雖然用PreparedStatement來代替Statement會使代碼多出幾行,但這樣的代碼無論從可讀性還是可維護性上來說.都比直接用Statement的代碼高很多檔次:
3:安全性
PreparedStatement可以防止SQL注入攻擊,而Statement卻不能。

數據庫連接池作用

1、限定數據庫的個數,不會導致由於數據庫連接過多導致系統運行緩慢或崩潰
2、數據庫連接不需要每次都去創建或銷燬,節約了資源
3、數據庫連接不需要每次都去創建,響應時間更快。

InnoDB、Mysaim的特點?

innoDB是默認的數據庫存儲引擎(支持高併發[寫])行鎖
外鍵
事務
行表鎖
緩存

Mysaim讀快
兩種類型都有⾃⼰優缺點,選擇那個完全要看⾃⼰的實際類弄。

⾏鎖,表鎖;樂觀鎖,悲觀鎖,共享鎖,排它鎖?

a. ⾏鎖:數據庫表中某⼀⾏被鎖住。
b. 表鎖:整個數據庫表被鎖住。
c. 樂觀鎖:顧名思義,就是很樂觀,每次去拿數據的時候都認爲別⼈不會修改,具體實現是給表增加⼀個版本號的字
段,在執⾏update操作時⽐較該版本號是否與當前數據庫中版本號⼀致,如⼀致,更新數據,反之拒絕。
d. 悲觀鎖:顧名思義,就是很悲觀,每次去拿數據的時候都認爲別⼈會修改。讀數據的時候會上鎖,直到update完成才
釋放鎖,使⽤悲觀鎖要注意不要鎖住整個表。
讀鎖(共享鎖):針對同一份數據,多個讀操作可以同時進行而不會互相影響。
寫鎖(排它鎖):當前寫操作沒有完成前,它會阻斷其他寫鎖和讀鎖。

數據庫隔離級別

常看當前數據庫的事務隔離級別:show variables like 'tx_isolation';
在這裏插入圖片描述
這就是事務還沒提交,而別的事務可以看到他其中修改的數據的後果,也就是髒讀。
可重複讀雖然讀取同一條數據可以保證一致性,但是卻不能保證沒有插入新的數據

MySQL主從複製的基本原理。

1、master將改變記錄到⼆進制⽇志(binary log)中(這些記錄叫做⼆進制⽇志事件,binary log events,可以通過show
binlog events進⾏查看);
2、slave將master的binary log events拷⻉到它的中繼⽇志(relay log);
3、slave重做中繼⽇志中的事件,將改變反映它⾃⼰的數據。
在這裏插入圖片描述

select * from table t where size > 10 group by size order by size的sql語句執⾏順序?

sql語句執⾏順序如下:
where -> group by -> having -> select -> orderby

數據庫事務的⼏種粒度;

a. 表鎖定:對整個表的鎖定。
b. ⾏鎖定:只鎖定進⾏更改的⾏,例如:insert,update,delete,都隱式採⽤⾏鎖定。
c. 數據庫鎖機制可分爲多種粒度的: 數據庫,表,⻚⾯,⾏
d. 粒度越⼤,DBMS管理越容易,但是實現併發處理的能⼒就越差,表,⻚⾯,⾏

mysql調優:

定位:查找、定位慢查詢
a) 創建索引:創建合適的索引,我們就可以現在索引中查詢,查詢到以後直接找對應的記錄。
b) 分表 :當一張表的數據比較多或者一張表的某些字段的值比較多並且很少使用時,採用水平分表和垂直分表來優化
c) 讀寫分離:當一臺服務器不能滿足需求時,採用讀寫分離的方式進行集羣。
d) 緩存:使用redis來進行緩存
e) 一些常用優化技巧(遵循範式,選擇合適的存儲引擎)

a. explain select語句;
b. 當只要⼀條數據時使⽤limit 1;
c. 爲搜索字段建索引;
d. 避免select *;
e. 字段儘量使⽤not null;
f. 垂直分割;
g. 拆分⼤的delete和insert語句:delete和insert會鎖表;
h. 分表分庫分區。

mysql索引結構

BTree索引
在這裏插入圖片描述
B+Tree索引
在這裏插入圖片描述
B+Tree(指針)與B-Tree 的區別


 
 1)B-樹的關鍵字和記錄是放在一起的,葉子節點可以看作外部節點,不包含任何信息;B+樹的非葉子節點中只有關鍵字和指向下一個節點的索引,記錄只放在葉子節點中。
  2)在B-樹中,越靠近根節點的記錄查找時間越快,只要找到關鍵字即可確定記錄的存在;而B+樹中每個記錄的查找時間基本是一樣的,都需要從根節點走到葉子節點,而且在葉子節點中還要再比較關鍵字。從這個角度看B-樹的性能好像要比B+樹好,而在實際應用中卻是B+樹的性能要好些。因爲B+樹的非葉子節點不存放實際的數據,這樣每個節點可容納的元素個數比B-樹多,樹高比B-樹小,這樣帶來的好處是減少磁盤訪問次數。儘管B+樹找到一個記錄所需的比較次數要比B-樹多,但是一次磁盤訪問的時間相當於成百上千次內存比較的時間,因此實際中B+樹的性能可能還會好些,而且B+樹的葉子節點使用指針連接在一起,方便順序遍歷(例如查看一個目錄下的所有文件,一個表中的所有記錄等),這也是很多數據庫和文件系統使用B+樹的緣故。 
 
思考:爲什麼說B+樹比B-樹更適合實際應用中操作系統的文件索引和數據庫索引? 
1) B+樹的磁盤讀寫代價更低 
  B+樹的內部結點並沒有指向關鍵字具體信息的指針。因此其內部結點相對B 樹更小。如果把所有同一內部結點的關鍵字存放在同一盤塊中,那麼盤塊所能容納的關鍵字數量也越多。一次性讀入內存中的需要查找的關鍵字也就越多。相對來說IO讀寫次數也就降低了。 
2) B+樹的查詢效率更加穩定 
  由於非終結點並不是最終指向文件內容的結點,而只是葉子結點中關鍵字的索引。所以任何關鍵字的查找必須走一條從根結點到葉子結點的路。所有關鍵字查詢的路徑長度相同,導致每一個數據的查詢效率相當。

聚簇索引與非聚簇索引
聚簇索引並不是一種單獨的索引類型,而是一種數據存儲方式。
術語‘聚簇’表示數據行和相鄰的鍵值聚簇的存儲在一起。
如下圖,左側的索引就是聚簇索引,因爲數據行在磁盤的排列和索引排序保持一致。
在這裏插入圖片描述

聚簇索引的好處:
按照聚簇索引排列順序,查詢顯示一定範圍數據的時候,由於數據都是緊密相連,數據庫不不用從多個數據塊中提取數據,所以節省了大量的io操作。
聚簇索引的限制:
對於mysql數據庫目前只有innodb數據引擎支持聚簇索引,而Myisam並不支持聚簇索引。
由於數據物理存儲排序方式只能有一種,所以每個Mysql的表只能有一個聚簇索引。一般情況下就是該表的主鍵。

爲了充分利用聚簇索引的聚簇的特性,所以innodb表的主鍵列儘量選用有序的順序id,而不建議用無序的id,比如uuid這

如何優化數據庫性能(索引、分庫分表、批置操作、分⻚算法、升級硬盤SSD、業務優化、主從部署)

1、選擇合適的數據庫引擎,合理使⽤索引
2、分⻚獲取數據,只獲取需要的字段
3、優化業務邏輯,減少數據庫IO
4、分庫分表
5、部署主從數據庫
6、升級硬件

SQL什麼情況下不會使⽤索引(讀)(不包含,不等於,函數)

a. select * 可能導致不⾛索引;
b. 空值會導致不⾛索引,因爲hashset不能存空值;
c. 索引列有函數運算,不⾛索引,可以在索引列建⽴⼀個函數的索引。

d. 隱式轉換可能導致不⾛索引;
e. 表的數據庫⼩或者需要選擇⼤部分數據,不⾛索引;
f. !=或者<>可能導致不⾛索引;
g. 字符型的索引列會導致優化器認爲需要掃描索引⼤部分數據且聚簇因⼦很⼤,最終導致棄⽤索引掃描⽽改⽤全表掃描
⽅式
h. like ‘%liu’ 百分號在前不⾛索引;
i. not in, not exist不⾛索引;

—般在什麼字段上建索引(過濾數據最多的字段)

1、表的主鍵、外鍵必須有索引;
2、數據量超過300的表應該有索引;
3、經常與其他表進⾏連接的表,在連接字段上應該建⽴索引;
4、經常出現在Where⼦句中的字段,特別是⼤表的字段,應該建⽴索引;

5、索引應該建在選擇性⾼的字段上;
6、索引應該建在⼩字段上,對於⼤的⽂本字段甚⾄超⻓字段,不要建索引;

mysql存儲引擎中索引的實現機制;

mysql索引的實現原理

查找慢查詢並定位慢查詢?

在項目自驗項目轉測試之前,在啓動mysql數據庫時開啓慢查詢,並且把執行慢的語句寫到日誌中,在運行一定時間後。通過查看日誌找到慢查詢語句。
1、關閉數據庫服務器(關閉服務)
2、把慢查詢記錄到日誌中
在這裏插入圖片描述
3、設置慢查詢時間
在這裏插入圖片描述
4.找出日誌中的慢查詢SQL
使用explain 慢查詢語句,來詳細分析語句的問題
在這裏插入圖片描述

索引使用小技巧?

1. 對於創建的多列索引(複合索引),不是使用的第一部分就不會使用索引。
alter table dept add index my_ind (dname,loc); // dname 左邊的列,loc就是右邊的列
explain select * from dept where dname='aaa'\G 會使用到索引
explain select * from dept where loc='aaa'\G 就不會使用到索引

2. 對於使用like的查詢,查詢如果是’%aaa’不會使用到索引而‘aaa%’會使用到索引。
   explain select * from dept where dname like '%aaa'\G不能使用索引
   explain select * from dept where dname like 'aaa%'\G使用索引.
所以在like查詢時,‘關鍵字’的最前面不能使用 % 或者 _這樣的字符.,如果一定要前面有變化的值,則考慮使用 全文索引->sphinx.

3. 如果條件中有or,有條件沒有使用索引,即使其中有條件帶索引也不會使用。換言之,就是要求使用的所有字段,都必須單獨使用時能使用索引.
   

4. 如果列類型是字符串,那一定要在條件中將數據使用引號引用起來。否則不使用索引。
expain select * from dept where dname=’111’;
expain select * from dept where dname=111;(數值自動轉字符串)
expain select * from dept where dname=qqq;報錯
也就是,如果列是字符串類型,無論是不是字符串數字就一定要用 ‘’ 把它包括起來.
5. 如果mysql估計使用全表掃描要比使用索引快,則不使用索引。
   表裏面只有一條記錄

數據庫優化之分表?

水平分表策略:
	1.按時間分表
 這種分表方式有一定的侷限性,當數據有較強的實效性,如微博發送記錄、微信消息記錄等,這種數據很少有用戶會查詢幾個月前的數據,如就可以按月分表。
	2.按區間範圍分表
 一般在有嚴格的自增id需求上,如按照user_id水平分表:
	table_1  user_id從1~100w 
	table_2  user_id從101~200w 
	table_3  user_id從201~300w 
	3.hash分表*****
 通過一個原始目標的ID或者名稱通過一定的hash算法計算出數據存儲表的表名,然後訪問相應的表。

語句優化小技巧

DDL優化:
1 、通過禁用索引來提供導入數據性能 。 這個操作主要針對有數據庫的表,追加數據
//去除鍵
alter table test3 DISABLE keys;
//批量插入數據
insert into test3 select * from test;
//恢復鍵
alter table test3 ENABLE keys;

2、 關閉唯一校驗
set unique_checks=0 關閉
set unique_checks=1 開啓

3、修改事務提交方式(導入)(變多次提交爲一次)
set autocommit=0 關閉
//批量插入
set autocommit=1 開啓

DML優化(變多次提交爲一次)
insert into test values(1,2);
insert into test values(1,3);
insert into test values(1,4);
//合併多條爲一條
insert into test values(1,2),(1,3),(1,4)

count(*),count(1)和count(字段)的區別

1)在表沒有主鍵時,count(1)比count(*)快;

2)有主鍵時,主鍵作爲計算條件,count(主鍵)效率最高;

3)若表格只有一個字段,則count(*)效率較高。

非關係型數據庫

redis詳解

有沒有使用過redis? Redis是什麼

key-value的nosql數據庫
做緩存數據庫的數據和web集羣時當做中央緩存存放seesion
單線程 + 多路IO複用.

Redis五大數據類型

Redis持久化

Redis主從複製

哨兵模式

心跳檢測假死的master

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章