面試官常問的資料庫問題(二)

面試官常問的資料庫問題 11–21

oracle:可在不同平臺執行(ISO標準認證);支援PL-SQL指令碼語言;效能很高;

sqlserver:只可在 windows 平臺執行;支援T-SQL指令碼語言;多使用者效能較低;

區別:

1、最大的區別在於平臺。oracle 可以執行在不同的平臺上;sqlserver 只能執行在 windows 平臺上。windows 平臺的穩定性和安全性,影響了 sqlserver 的穩定性和安全性。

2、oracle 使用的指令碼語言為 PL-SQL,而 sqlserver 使用的指令碼為 T-SQL 。文體結構不同

3、體系結構不同。

oracle的檔案體系結構為:

sql server的檔案體系結構為:

4、儲存結構不同。

﹣oracle儲存結構:

在oracle裡有兩個塊引數pctfree(填充因子)和pctused(複用因子),可控制塊確定塊本身何時有,何時沒有足夠的空間接受新資訊(對塊的儲存情況的分析機制)。這樣可降低資料行連線與行遷移的可能性。塊的大小可設定(oltp塊和dss塊)。

在oracle中,將連續的塊組成區,可動態分配區(區的分配可以是等額的也可以是自增長的)可減少空間分配次數。

在oraclel裡表可以分為多個段,段由多個區組成,每個段可指定分配在哪個表空間裡(段的型別分為:資料段、索引段、回滾段、臨時段、cash段。oracle裡還可對錶進行分割槽,可按照使用者定義的業務規則、條件或規範,物理的分開磁碟上的資料。

這樣大大降低了磁碟爭用的可能性。

oracle有七個基本表空間:

不同的資料分別放在不同的表空間(資料字典與真實資料分開存放),在oracle裡基表(儲存系統引數資訊)是加密儲存,任何人都無法訪問。只能透過使用者可視檢視檢視。

﹣sql server 儲存結構:

以頁為最小分配單位,每個頁為8k(不可控制,缺乏對頁的儲存情況的分析機制),可將8個連續的頁的組成一個‘擴充套件’,以進一步減少分配時所耗用的資源。(分配缺乏靈活性),在sql server裡資料以表的方式存放,而表是存放在資料庫裡。

sql server有五個基本資料庫

真實資料與資料字典存放在一起。對系統引數資訊無安全機制。

關係型資料庫:可用 SQL 語句在一個以上表之間做非常複雜的資料查詢;安全性高;資料儲存在硬碟;

非關係型資料庫:效能高;可擴充套件(水平擴充套件);資料儲存在快取,比關係型資料庫查詢快;

﹣非關係型資料庫的優勢:

效能:NOSQL 是基於鍵值對的,可以想象成表中的主鍵和值的對應關係,而且不需要經過 SQL 層的解析,所以效能非常高。

可擴充套件性:同樣也是因為基於鍵值對,資料之間沒有耦合性,所以非常容易水平擴充套件。

﹣關係型資料庫的優勢:

複雜查詢:可以用 SQL 語句在一個表以及多個表之間做非常複雜的資料查詢。

事務支援:使得對於安全效能很高的資料訪問要求得以實現。

MySql主要有兩種儲存引擎:InnoDB和MyISAM。

InnoDB:支援事務、外來鍵;支援行級鎖;聚集索引;不儲存行數;不支援全文型別索引(查表總行數時,不需要全表掃描);

MyISAM:不支援事務、外來鍵;支援表級鎖(效能低);非聚集索引;儲存行數;支援全文型別索引(查表總行數時,全表掃描);

使用場景:一般預設InnoDB,當表比較小,讀取操作較多,插入和更新少,不要考慮事務,可以考慮MyIsam。

區別

InnoDB支援事務,後者不支援

InnoDB支援外來鍵,MyIsam不支援

InnoDB支援行級鎖,MyIsam是表級鎖,表級鎖效能低

InnoDB是聚集索引,即索引中鍵值的邏輯順序決定了表中相應行的物理順序,而MyIsam是非聚集索引,即索引中索引的邏輯順序與磁碟上行的物理儲存順序不同。

InnoDB不儲存行數,後者儲存。

使用場景,一般預設都是InnoDB,如果表比較小,讀取操作較多,插入和更新操作少,不需要考慮事務,可以考慮MyIsam

①.效能方面:redis 要大於 mongodb ;

②.操作便利性:Mongodb 支援豐富的資料表達、索引,最類似關係型資料庫,支援的查詢語言非常豐富 ;Redis 資料結構方面豐富

③.記憶體空間大小和資料量大小:Mongodb 適合大量資料的儲存 ;

④.資料一致性:Redis 事務支援比較弱 ;Mongodb 不支援事務 ;

⑤.應用場景:Redis 用在資料量較小的操作和運算上;Mongodb 主要解決海量資料的訪問效率問題。

redis、memcache、mongoDB 對比

從以下幾個維度,對redis、memcache、mongoDB 做了對比,歡迎拍磚

1、效能

都比較高,效能對我們來說應該都不是瓶頸

總體來講,TPS方面redis和memcache差不多,要大於mongodb

2、操作的便利性

memcache資料結構單一

redis豐富一些,資料操作方面,redis更好一些,較少的網路IO次數

mongodb支援豐富的資料表達,索引,最類似關係型資料庫,支援的查詢語言非常豐富

3、記憶體空間的大小和資料量的大小

redis在2.0版本後增加了自己的VM特性,突破物理記憶體的限制;可以對key value設定過期時間(類似memcache)

memcache可以修改最大可用記憶體,採用LRU演算法

mongoDB適合大資料量的儲存,依賴作業系統VM做記憶體管理,吃記憶體也比較厲害,服務不要和別的服務在一起

4、可用性(單點問題)

對於單點問題

redis,依賴客戶端來實現分散式讀寫;主從複製時,每次從節點重新連線主節點都要依賴整個快照,無增量複製,因效能和效率問題,

所以單點問題比較複雜;不支援自動sharding,需要依賴程式設定一致hash 機制。

一種替代方案是,不用redis本身的複製機制,採用自己做主動複製(多份儲存),或者改成增量複製的方式(需要自己實現),一致性問題和效能的權衡

Memcache本身沒有資料冗餘機制,也沒必要;對於故障預防,採用依賴成熟的hash或者環狀的演算法,解決單點故障引起的抖動問題。

mongoDB支援master-slave,replicaset(內部採用paxos選舉演算法,自動故障恢復),auto sharding機制,對客戶端遮蔽了故障轉移和切分機制。

5、可靠性(持久化)

對於資料持久化和資料恢復

redis支援(快照、AOF):依賴快照進行持久化,aof增強了可靠性的同時,對效能有所影響

memcache不支援,通常用在做快取,提升效能;

MongoDB從1.8版本開始採用binlog方式支援持久化的可靠性

6、資料一致性(事務支援)

Memcache 在併發場景下,用cas保證一致性

redis事務支援比較弱,只能保證事務中的每個操作連續執行

mongoDB不支援事務

7、資料分析

mongoDB內建了資料分析的功能(mapreduce),其他不支援

8、應用場景

redis:資料量較小的更效能操作和運算上

memcache:用於在動態系統中減少資料庫負載,提升效能;做快取,提高效能(適合讀多寫少,對於資料量比較大,可以採用sharding)

MongoDB:主要解決海量資料的訪問效率問題

①.儲方式:Memcached 資料都在記憶體中,斷電後會掛掉,資料不可超過記憶體大小;Redis 部分存在硬碟上,保證資料的永續性 ;

②.資料支援型別:Memcached 對資料型別支援相對簡單 ;Redis 有複雜的資料型別 ;

③.Value 大小:Redis 最大可以達到 1G;Memcached 只有 1MB。

快取資料(查詢多刪改少的資料)比如:資料字典(改動少,基本不改動)

為什麼使用快取?

快取主要用途有兩個,高效能和高併發。

高併發的場景不常見,所以專案用它的目的是高效能。

如果一個數據被大量的讀取,那麼可以將它放入快取中,被讀取時直接從快取中透過key查出value,這樣可以大幅提升效能。

使用快取存在哪些問題?

﹣①快取雪崩。

﹣②快取穿透。

﹣③快取與資料量雙寫不一致。

﹣④快取併發競爭。

持久化:將記憶體中的資料寫入到硬碟中。

Redis實現資料持久化的兩種實現方式:1、RDB實現Redis資料持久化(預設方式);2、AOF持久化方案;

RDB:指定的時間間隔內儲存資料快照;

AOF:先把命令追加到操作日誌的尾部,儲存所有的歷史操作;

RDB:將資料寫入到一個臨時檔案(dump.rdb),持久化結束之後,用這個臨時檔案替換上次持久化的檔案,達到資料恢復。

間隔一段時間進行持久化,如果持久化之間 redis 發生故障,會發生資料丟失,所以這種方式更適合資料要求不嚴謹的時候,

預設開啟的 AOF:是將執行過的指令記錄下來,資料恢復時按照從前到後的順序再將指令執行一遍,實現資料恢復。

AOF 相比於RDB的優點:可以保證資料完整,可對歷史操作進行處理;

但是 AOF 檔案比 RDB 檔案大,且恢復速度慢,預設是關閉的。

①.noeviction:預設策略,不刪除任意資料,但是記憶體不夠時,會直接返回錯誤

②.Allkeys-lru:從資料集中(包括設定過期時間和未設定過期時間的資料集),優先移除最近未使用的 key

③.Volatile-lru:在設定了過期時間的資料集中,優先移除最近未使用的 key

④.Allkeys-random:從資料集中(包括設定過期時間和未設定過期時間的資料集),隨機移除某個 key

⑤.Volatile-random:在設定了過期時間的資料集中,隨機移除某個 key Volatile-ttl:在設定了過期時間的資料集中,具有更早過期時間的 key 優先移除。

Redis 的記憶體淘汰:使用者儲存的一些鍵可以被 redis 主動從例項中刪除,從而產生讀 miss 的情況,

記憶體淘汰是為了更好的使用記憶體,用一定的快取 miss 來換取記憶體的使用率。

﹣Redis 提供的記憶體淘汰策略有:

①.noeviction:預設策略,不刪除任意資料,但是記憶體不夠時,會直接返回錯誤

②.Allkeys-lru:從資料集中(包括設定過期時間和未設定過期時間的資料集),優先移除最近未使用的 key

③.Volatile-lru:在設定了過期時間的資料集中,優先移除最近未使用的 key

④.Allkeys-random:從資料集中(包括設定過期時間和未設定過期時間的資料集),隨機移除某個 key

⑤.Volatile-random:在設定了過期時間的資料集中,隨機移除某個 key Volatile-ttl:在設定了過期時間的資料集中,具有更早過期時間的 key 優先移除。

redis 的雪崩、穿透

快取穿透

什麼是快取穿透?

一般的快取系統,都是按照key(鍵)去快取查詢,如果不存在對應的value(值),就應該去DB(資料庫)中查詢 。

這個時候,如果請求的併發量很大,就會對後端的DB系統造成很大的壓力。這就叫做快取穿透!

造成的原因:

業務自身程式碼或資料出現問題;

一些惡意攻擊、爬蟲造成大量空的命中,此時會對資料庫造成很大壓力。

解決方法:

設定布隆過濾器,將所有可能存在的資料雜湊到一個足夠大的bitmap中,一個一定不存在的資料會被這個bitmap攔截掉,

從避免了對底層儲存系統的查詢壓力。

如果一個查詢返回的資料為空,不管是資料不存在還是系統故障,我們仍然把這個結果進行快取,但是它的過期時間會很短

最長不超過5分鐘。

服務雪崩

什麼是雪崩?

因為快取層承載了大量的請求,有效的保護了儲存層。但是如果快取由於某些原因,整體不能夠提供服務,於是所有的請求,就會到達儲存層,儲存層的呼叫量就會暴增,造成儲存層也會掛掉的情況。

快取雪崩的英文解釋是奔逃的野牛,指的是快取層當掉之後,併發流量會像奔騰的野牛一樣,大量後端儲存。

造成的原因:

當快取伺服器重啟或者大量快取集中在某一個時間段失效,這樣在失效的時候,大量資料會去直接訪問DB,此時給DB很大的壓力。

解決方法:

設定redis叢集和DB叢集的高可用,如果redis出現宕機情況,可以立即由別的機器頂替上來。這樣可以防止一部分的風險。

使用互斥鎖

在快取失效後,透過加鎖或者佇列來控制讀和寫資料庫的執行緒數量。比如:對某個key只允許一個執行緒查詢資料和寫快取,其他執行緒等待。單機的話,可以使用synchronized或者lock來解決,如果是分散式環境,可以是用redis的setnx命令來解決。

不同的key,可以設定不同的過期時間,讓快取失效的時間點不一致,儘量達到平均分佈。

永遠不過期

redis中設定永久不過期,這樣就保證了,不會出現熱點問題,也就是物理上不過期。

資源保護

使用netflix的hystrix,可以做各種資源的執行緒池隔離,從而保護主執行緒池。

String(字串)、Hash(雜湊)、List(列表)、Sets(集合)、ZSet(有序集合)

①.String(字串):redis 最基本的資料型別,一個 key 對應一個 value,一個鍵最大能儲存 512MB

②.Hash(雜湊):是一個鍵值對集合,特別適合用於儲存物件

③.List(列表):存放多個字串值,可以重複,按照插入順序進行排序,也可以新增一個元素到列表的頭部和尾部

④.Sets(集合):存放多個值,不可以重複,沒有順序

⑤.ZSet(有序集合):存放多個值,不可以重複,有順序。不同的是每個元素都會關聯一個 double 型別的分數,redis 正是透過分 數來為集合中的成員進行從小到大的排序

①.快取熱資料(熱資料:查詢多刪改少的資料 )

②.計數器,諸如統計點選數等應用

③.佇列

④.位操作(大資料處理),比如統計 QQ 使用者線上

⑤.分散式鎖和單執行緒機制

⑥.最新列表

⑦.排行榜,使用 zadd 新增有序集合

redis使用場景:會話快取(Session Cache)、全頁快取(FPC)、排行榜/計數器

﹣redis優點:

速度快,因為資料存在記憶體中,類似於HashMap,HashMap的優勢就是查詢和操作的時間複雜度都是O(1)

支援豐富資料型別,支援string,list,set,sorted set,hash

支援事務,操作都是原子性,所謂的原子性就是對資料的更改要麼全部執行,要麼全部不執行

豐富的特性:可用於快取,訊息,按key設定過期時間,過期後將會自動刪除

在GRADE表中查詢80–90份的學生學號和分數

在GRADE 表中查詢課程編號為003學生的平均分

在GRADE 表中查詢學習各門課程的人數

查詢所有姓張的學生的學號和姓名

查詢和學號’0001’的這位同學性別相同的所有同學的姓名和出生年月

查詢所有選修課程編號為0002 和0003的學生的學號、姓名和性別

查詢出學號為0001的學生的分數比0002號學生最低分高的課程編號的課程編號和分數

查詢分數在80–90分的學生的學號、姓名、分數

查詢學習了’C語言’課程的學生學號、姓名和分數

查詢所有學生的總成績,要求列出學號、姓名、總成績,沒有選課的學生總成績為空。

※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※

我是「數據分析那些事」。常年分享數據分析乾貨,不定期分享好用的職場技能工具。各位也可以關注我的Facebook,按讚我的臉書並私訊「10」,送你十週入門數據分析電子書唷!期待你與我互動起來~

文章推選

面試官常問的資料庫問題(一)

一張圖講清如何正確應用視覺化圖表,學會後再也不會用錯圖表

Python 的學習線路圖,以及100 個 Python 小專案原始碼分享,碼住!

這是一個專注於數據分析職場的內容部落格,聚焦一批數據分析愛好者,在這裡,我會分享數據分析相關知識點推送、(工具/書籍)等推薦、職場心得、熱點資訊剖析以及資源大盤點,希望同樣熱愛數據的我們一同進步! 臉書會有更多互動喔:https://www.facebook.com/shujvfenxi/

這是一個專注於數據分析職場的內容部落格,聚焦一批數據分析愛好者,在這裡,我會分享數據分析相關知識點推送、(工具/書籍)等推薦、職場心得、熱點資訊剖析以及資源大盤點,希望同樣熱愛數據的我們一同進步! 臉書會有更多互動喔:https://www.facebook.com/shujvfenxi/