41.數據庫id自增解決方案
數據庫集群的情況下,如果自動增長id產生重復的話,如何解決?
1.采用UUID形式設置為id。
缺點:無規則,沒有順序。如果是Oracle數據庫,推薦使用。
2.設置步長。缺點:不利於后期服務器的擴容。
在數據庫集群環境下,默認自增方式存在問題,因為都是從1開始自增,可能會存在重復,應該設置每台節點自增步長不同。
查詢自增的步長
SHOW VARIABLES LIKE 'auto_increment%'
修改自增的步長
SET @@auto_increment_increment=10;
修改起始值
SET @@auto_increment_offset=5;
假設有兩台mysql數據庫服務器
節點①自增 1 3 5 7 9 11 ….
節點②自增 2 4 6 8 10 12 ….
缺點:在最開始設置好了每台節點自增方式步長后,確定好了mysql集群數量后,無法擴展新的mysql,不然生成步長的規則可能會發生變化。
假設有三台MySql服務器集群,三台服務器分別的起始值和步長為多少?
起始值為 1 2 3.,步長為3.
其它方案:使用Redis、雪花算法。
使用Redis:是單線程,如果是多線程的情況下,會產生線程阻塞,不推薦。如果是量小,不是特別多的情況下,可以使用redis和雪花算法。
2. 數據庫分表分庫策略
1. 在數據庫分表分庫原則中,遵循二個設計理論 垂直拆分、水平拆分。垂直拆分是把不同的表拆到不同的數據庫中,而水平拆分是把同一個表拆到不同的數據庫中。
垂直拆分:就是根據不同的業務進行拆分的,拆分成不同的數據庫,比如會員數據庫、訂單數據庫、支付數據庫、消息數據庫等,垂直拆分在大型電商項目中使用比較常見。
優點:拆分后業務清晰,拆分規則明確,系統之間整合或擴展更加容易。
缺點:部分業務表無法join,跨數據庫查詢比較繁瑣(必須通過接口形式通訊(http+json))、會產生分布式事務的問題,提高了系統的復雜度。舉栗子:不可能出現,在訂單服務中,訂單服務直接連接會員服務的數據庫這種情況。
水平拆分:把同一張表中的數據拆分到不同的數據庫中進行存儲、或者把一張表拆分成 n 多張小表。
相對於垂直拆分,水平拆分不是將表的數據做分類,而是按照某個字段的某種規則來分散到多個庫之中,每個表中包含一部分數據。簡單來說,我們可以將數據的水平切分理解為是按照數據行的切分,就是將表中 的某些行切分到一個數據庫,而另外的某些行又切分到其他的數據庫中,主要有分表,分庫兩種模式 該方式提高了系統的穩定性跟負載能力,但是跨庫join性能較差。
使用MyCat實現水平分片策略
MyCat支持10種分片策略
1、求模算法
2、分片枚舉
3、范圍約定
4、日期指定
5、固定分片hash算法
6、通配取模
7、ASCII碼求模通配
8、編程指定
9、字符串拆分hash解析
詳細:http://www.mycat.io/document/mycat-definitive-guide.pdf
使用MyCat實現水平分片策略
分片枚舉
分片枚舉算法:就是根據不同的枚舉(常量),進行分類存儲的。舉栗子:有些業務需要按照省份或區縣來做保存,而全國的省份區縣固定的,這類業務使用這一規則。
環境搭建:
1.案例步驟: 創建數據庫userdb_1 、 userdb_2、userdb_3
2.修改partition-hash-int.txt 規則 sahgnhai=0、beijing=1、shenzhen=2,定義枚舉(地區) 每個地區指定的數據庫存放位置。
根據地區進行分庫 上海數據庫、北京數據庫 、深圳數據庫。
求模算法
求摸法分片,根據id進行十進制求摸運算,運算結果為分區索引
注意:數據庫節點分片數量無法更改。 和ES集群非常相似的。
MyCat如何實現通過一個sql 就可以查詢出來所有的表的數據
舉栗子:在mycat中執行 select * from user_info; 這個簡單的sql查詢可以查詢出來對應所有分表的數據。
原因:mycat中的 一個 sql 語句,相當於三個sql 語句在不同的數據表都進行查詢。
select * from db1_user_info;
select * from db2_user_info;
select * from db3_user_info;
然后三條語句查詢出來的結果進行組裝在返回給mycat。
MyCat分片字段的查詢
select * from user_info where id=1;
1.如果是根據MyCat的分片字段作為條件進行查詢,則只會有一條匹配到對應分片字段的數據表中執行sql語句查詢。
2.如果查詢的條件是非分片字段,則會在每個分表中都會執行sql語句。如果查詢條件不是根據分片字段作為條件去查詢,不建議使用mycat。
MyCat分頁查詢的原理
select * from user_info limit 0,3;
執行分頁查詢語句,會在每一個分表中都執行該sql語句,但是mycat 返回的結果就是從這三個返回的結果集中隨機的抽取一對進行數據顯示。
效果圖如下,查詢所有的數據如下:
分頁查詢sql語句,下面是同一條sql 執行三次 查詢出來的結果,查詢出來的結果是隨機的,可能執行三次查詢出來的結果都一樣的。
數據庫集群產生的問題
1.數據庫關聯查詢的問題(水平拆分導致的)
2.數據同步的問題
3.id自增的問題