資料庫面試題1
1.資料庫自增主鍵可能的問題
【
1、當資料庫匯出之後重新匯入(備份再恢復),主鍵會重新生成,如果有其他的表以這個主鍵作為外來鍵,那麼會導致這個關聯關係不存在。
2、資料量特別大時,會導致查詢資料庫操作變慢。此時需要進行資料庫的水平拆分,劃分到不同的資料庫中,那麼當新增資料時,每個表都會自增長,導致主鍵衝突。
】
在MySQL中經常會配置自增長屬性的欄位作為主鍵,特別是使用InnoDB儲存引擎,
因為InnoDB的聚集索引的特性,使用自增長屬性的欄位當主鍵效能更好,但是使用自增主鍵也可能會帶來一些問題。
舉個例子,使用自增主鍵對資料庫做分庫分表,可能出現一些諸如主鍵重複等的問題,或者在資料庫匯入的時候,可能會因為主鍵出現一些問題。
主要業務表的主鍵應該配置一個合理的策略,儘量避免自增AUTO_INCREMENT。
針對主鍵自增可能產生的問題,下面這兩篇文章有相關的討論:
INNODB自增主鍵的一些問題
mysql自增列導致主鍵重複問題分析
針對主鍵增長方式的解決方案
來自知乎問題-高併發網站如何解決資料庫主鍵自增的時候出現重複?
2.資料庫自增主鍵可能的問題,如何解決
1)依賴資料庫自增機制達到全域性ID唯一併消除單點
在2的基礎上,部署兩個(多個)資料庫例項,
設定自增步長為2(多個則為例項數),即auto-increment-increment = 2
設定auto-increment-offset分別為1,2.....
這樣第一臺資料庫伺服器的自增id為 1 3 5 7 9
第二臺為2 4 6 8 10
2)使用uuid
解決的辦法有兩個方向,一個是在應用層做處理,一個是資料庫上去做處理
3)給每個資料庫設定不同的開始id
資料庫1 從 10000.. 開始
資料庫2 從 20000.. 開始
這種辦法不依賴於其他服務實現id唯一性,即時其他資料庫掛了依然能生成id
4)使用一個庫專門生成id
id列不設自增,由應用設定id
建立單獨的id生成資料庫,庫中建立多個id生成表,每個表如下
+-------------------+------+ | id | stub | +-------------------+------+ | 72157623227190423 | a | +-------------------+------+
每次插入資料時先從該庫的對應id生成表中更新id
REPLACE INTO Tickets64 (stub) VALUES ('a');
SELECT LAST_INSERT_ID();
執行後表內資料id增加1,並返回新id
然後使用該id插入到表中,這種方法的好處是能夠統計每個表的資料量
5)使用Redis分批次生成id
redis中儲存一個id的 當前批次值 ,應用每次獲取該值的時候增加1,每個批次的數量是固定的
比如批次10,開始id為 10 x 1000 結束id為 (10 + 1) x 1000 - 1
id使用完成後再去獲取一個批次id