- 會寫sql語句就可以了,為什么要了解MySQL索引的原理?
- curd我都會,為什么要了解undolog和redolog?
- 我又不需要修改MySQL源碼,為什么要了解MySQL的鎖?
酸奶爸爸曾經(jīng)也思考過上述問題,MySQL常用功能我都會,為什么面試官要問索引原理、undolog等技術(shù)細節(jié)呢?直到后來我遇到下面問題。
酸奶爸爸負責的項目每天有1000w的pv,正常業(yè)務(wù)使用MySQL+Redis能夠抗住正常的業(yè)務(wù)訪問。訪問日志只從請求頭里打印了url和IP地址,但是每次調(diào)查線上問題讀日志的時候都需要用戶的地理位置信息,所以每次pv都需要記錄IP+地理位置,以方便后續(xù)閱讀日志文件。一個緊迫的需求就被提出來,通過IP地址快速獲取地理位置。
IP地址→地理位置
網(wǎng)上有現(xiàn)成的IP段與地理位置的對應(yīng)表,如果用MySQL這樣實現(xiàn)
create table ip_addr_table
(
ip_begin int not null,
ip_end int not null,
addr varchar(100) null
);
create index ip_addr_table_ip_begin_index
on ip_addr_table (ip_begin);
create index ip_addr_table_ip_end_index
on ip_addr_table (ip_end);
select addr from ip_addr_table where ip_begin<intip and ip_end>intip limit 1;
但是用MySQL實現(xiàn),每次請求都要額外查詢一次地理位置信息,系統(tǒng)訪問量又比較大,這讓MySQL本就不富裕的性能雪上加霜。能不能使用MySQL的索引原理自己實現(xiàn)IP地理位置的查詢呢?
酸奶爸爸在百度上谷歌后發(fā)現(xiàn)了這個。
ip2region 將ip與地理位置的數(shù)據(jù)寫入二進制文件,并生成數(shù)據(jù)區(qū)域(data)、聚簇索引(index)與非聚簇索引(header index)。
- 把ip值通過ip2long 轉(zhuǎn)為長整型
- 使用二分法在 HEADER INDEX 中搜索,比較得到對應(yīng)的 header index block
- header index block 指向 INDEX 中的一個 4K 分區(qū),所以直接把搜索范圍降低到 4K
- 采用二分法在獲取到的 4K 分區(qū)搜索,得到對應(yīng)的 index block
- 拿到該 index block 的后面四個字節(jié), 分別得到數(shù)據(jù)長度和數(shù)據(jù)地址
- 從數(shù)據(jù)地址讀取拿到的所得長度的字節(jié),即是搜索結(jié)果
數(shù)據(jù)庫文件的結(jié)構(gòu)和原理請閱讀 @冬芽 的blog:“ip2region數(shù)據(jù)庫文件的結(jié)構(gòu)和原理”
其實像MySQL、Redis這些經(jīng)典軟件為我們提供了很多實用的思想,當我們遇到類似問題的時候可以借鑒以下這些大神是怎么做的。
-
當需要將大量數(shù)據(jù)寫到不連續(xù)的空間的時候,想一想MySQL的redo log。
-
當有數(shù)據(jù)在同一時刻既存在讀競爭也存在寫競爭的時候,想一想MySQL的鎖。
-
當有一大波數(shù)據(jù)中的一部分數(shù)據(jù)需要淘汰的時候,想一想Redis的LFU。
知識本身不值錢,使用知識的過程才值錢。
本文摘自 :https://www.cnblogs.com/