1. 程式人生 > >資料庫面試題整理

資料庫面試題整理

1、exists和in有什麼區別?

  • EXISTS用於檢查子查詢是否至少會返回一行資料,該子查詢實際上並不返回任何資料,而是返回值True或False,而In子查詢則是返回具體的資料值,與指定的欄位比較
  • EXISTS與IN的使用效率的問題,通常情況下采用exists要比in效率高,因為IN不走索引,但要看實際情況具體使用
  • IN適合於外表大而內表小的情況;EXISTS適合於外表小而內表大的情況。(樓主還沒搞清楚原理)

2、解釋下SQL UNION 和 UNION ALL 操作符?

  • union和union all的都是兩張或多張表查詢的結果集合並起來,union會掉重複的記錄,unional不會去掉重複的記錄。union和union all使用的要求是兩個結果集的列資料相同,資料型別相同,順序相同

3、一張表有3個欄位,性別,姓名,年齡,用一條sql查詢出男的有多少條,女的有多少條?

  •   select sex,count(*) from 表 group by 性別

     或select sum( CASE WHEN sex = '男' THEN  1 ELSE 0 END  ) 男數量,sum( CASE WHEN sex = '女' THEN  1 ELSE 0 END  )  女數量  from      表

4、一張員工表,有個兩個欄位,分別是員工姓名和工資,假設>=1000就一級,小於1000就2級,用一條sql查詢出所有員工的等級?

  • SELECT 姓名,
  • CASE WHEN 工資 < 1000 THEN '2'
  • WHEN 工資 >= 1000 THEN '1'
  • ELSE NULL END 工資等級,
  • FROM Table_A

參考:http://www.cnblogs.com/prefect/p/5746624.html

           https://juejin.im/post/5a6873fbf265da3e393a97fa

5、MySQL中myisam與innodb的區別?

  5.1、InnoDB支援事物,而MyISAM不支援事物

  5.2、InnoDB支援行級鎖,而MyISAM支援表級鎖

  5.3、MyISAM的索引和資料是分開的,並且索引是有壓縮的,記憶體使用率就對應提高了不少。能載入更多索引,而Innodb是索引和資料是緊密捆綁的,沒有                  使用壓縮從而會造成Innodb比MyISAM體積龐大不小

  5.4、InnoDB支援外來鍵,而MyISAM不支援

  5.5、InnoDB不支援全文索引,而MyISAM支援。

6、mysql主從複製的原理?

  6.1、 主:binlog執行緒——記錄下所有改變了資料庫資料的語句,放進master上的binlog日誌中;

  6.2、 從:io執行緒——在使用start slave 之後,負責從master上拉取 binlog 日誌內容,放進 自己的relay log中;

  6.3、 從:sql執行執行緒——執行relay log中的語句;

7、在mysql索引優化方面,你有什麼經驗,說一說?

  索引本質上是一種基於儲存引擎級別的資料結構,所以不能拋開儲存引擎單單談索引的原理,如果是myisam和innodb的儲存引擎都是採用B+樹這種資料結構,資料表記錄節點都是按照鍵值大小順序存放在同一層的葉子節點上,myisam和innodb不同的是myisam儲存引擎葉節點的data域存放的是資料記錄的地址

參考:http://blog.csdn.net/ifollowrivers/article/details/73614549

8、在使用redis的過程中,我們往往是必須先拿到資料,根據資料進行判斷,進行一些處理後,再設定數值到redis伺服器中,在這過程中,你怎麼保證資料安全?

可以採用樂觀鎖,簡單的來我們每取一個數據的時候,redis不只是返回數值,還會返回這個數值對應的版本號,再設定值的到redis時,先檢查版本號,再設定更新,在redis命令的表現上就是取資料,操作資料之前,先watch資料。

9、redis是單執行緒的,一定可以保證資料安全嗎 ?一定,為什麼?不一定,什麼情況下不安全?什麼情況下安全?

   不一定

  不安全的情況:比如有個兩個redis連線,在併發的情況下,可能取到同一個值,比如都取到10,然後在程式碼中+1,預期中是12,但是實際上可能是11

  安全的情況:redis自增和自減命令

10、Redis的併發競爭問題如何解決了?解Redis事務的CAS操作嗎?

http://www.cnblogs.com/520playboy/p/8481935.html 快取機器增刪如何對系統影響最小,一致性雜湊的實現11、Redis持久化的幾種方式,優缺點是什麼,怎麼實現的?

reids有兩種持久化方案,分別是rdb和aof

http://www.cnblogs.com/520playboy/p/6017414.html

12、Redis的快取失效策略?

相關知識: redis 記憶體資料集大小上升到一定大小的時候,就會施行資料淘汰策略。redis 提供 6種資料淘汰策略:  volatile-lru:從已設定過期時間的資料集(server.db[i].expires)中挑選最近最少使用的資料淘汰

volatile-ttl:從已設定過期時間的資料集(server.db[i].expires)中挑選將要過期的資料淘汰

volatile-random:從已設定過期時間的資料集(server.db[i].expires)中任意選擇資料淘汰

allkeys-lru:從資料集(server.db[i].dict)中挑選最近最少使用的資料淘汰

allkeys-random:從資料集(server.db[i].dict)中任意選擇資料淘汰

no-enviction(驅逐):禁止驅逐資料

13、快取穿透的解決辦法?

快取穿透是查一個一定不存在的資料,可能導致資料庫掛掉

解決:http://www.cnblogs.com/520playboy/p/8249942.html

14、redis叢集,高可用,原理

通過主從複製,通過在從機配置,一主兩從,哨兵模式,主機掛點,從機自動升級為主機

15、mySQL裡有2000w資料,redis中只存20w的資料,如何保證redis中的資料都是熱點資料?

比如使用者資料。資料庫有2000w條。 活躍使用者: redis sortSet裡 放兩天內(為方便取一天內活躍使用者)登入過的使用者,登入一次ZADD一次,如set已存在則覆蓋其分數(登入時間)。鍵:login:users,值:分數 時間戳、value userid。設定一個週期任務,比如每天03:00:00點刪除sort set中前一天3點前的資料(保證set不無序增長、留近一天內活躍使用者)。

取時,拿到當前時間戳(int 10位),再減1天就可按分數範圍取過去24h活躍使用者。

16、mysql索引為什麼使用B+樹 先從資料結構的角度來答。 B-樹和B+樹最重要的一個區別就是B+樹只有葉節點存放資料,其餘節點用來索引,而B-樹是每個索引節點都會有Data域。 這就決定了B+樹更適合用來儲存外部資料,也就是所謂的磁碟資料。 從Mysql(Inoodb)的角度來看,B+樹是用來充當索引的,一般來說索引非常大,尤其是關係性資料庫這種資料量大的索引能達到億級別,所以為了減少記憶體的佔用,索引也會被儲存在磁碟上。 那麼Mysql如何衡量查詢效率呢?磁碟IO次數,提升mysql查詢效率,目的就是為了就少磁碟IO次數,當查詢資料的時候,最好的情況就是很快找到目標索引,然後讀取資料,使用B+樹就能很好的完成這個目的,但是B-樹的每個節點都有data域(指標),這無疑增大了節點大小,說白了增加了磁碟IO次數(磁碟IO一次讀出的資料量大小是固定的,單個數據變大,每次讀出的就少,IO次數增多,一次IO多耗時啊!),而B+樹除了葉子節點其它節點並不儲存資料,節點小,磁碟IO次數就少。這是優點之一。 另一個優點是什麼,B+樹所有的Data域在葉子節點,一般來說都會進行一個優化,就是將所有的葉子節點用指標串起來。這樣遍歷葉子節點就能獲得全部資料,這樣就能進行區間訪問啦

 參考:https://www.cnblogs.com/xyxxs/p/4440187.html

 17、資料庫會死鎖嗎,舉一個死鎖的例子,mysql怎麼解決死鎖?

用Use SHOW INNODB STATUS來確定最後一個死鎖的原因。這樣可以幫助你調節應用程式來避免死鎖。

http://sadwxqezc.github.io/HuangHuanBlog/mysql/2017/05/30/Innodb%E6%AD%BB%E9%94%81.html#3-工作中的另一個死鎖case