方法有很多,建二級緩存,把用戶登錄和所在的表名緩存在一起,很輕松就定位到了,
十年的密云網(wǎng)站建設(shè)經(jīng)驗,針對設(shè)計、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時及時工作處理。網(wǎng)絡(luò)營銷推廣的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動調(diào)整密云建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計,從而大程度地提升瀏覽體驗。創(chuàng)新互聯(lián)從事“密云網(wǎng)站設(shè)計”,“密云網(wǎng)站推廣”以來,每個客戶項目都認真落實執(zhí)行。
還可以用分表策略,每個登錄用戶賬號HASH一個值,做為表名的后綴,最多50個,都可以控制。
分表:你只要記住必須要根據(jù)什么來分這句話就可以了。
插入:總要用用戶名吧。根據(jù)他定位放到哪一張表里。
mysql分庫分表一般有如下場景
其中1,2相對較容易實現(xiàn),本文重點講講水平拆表和水平拆庫,以及基于mybatis插件方式實現(xiàn)水平拆分方案落地。
在 《聊一聊擴展字段設(shè)計》 一文中有講解到基于KV水平存儲擴展字段方案,這就是非常典型的可以水平分表的場景。主表和kv表是一對N關(guān)系,隨著主表數(shù)據(jù)量增長,KV表最大N倍線性增長。
這里我們以分KV表水平拆分為場景
對于kv擴展字段查詢,只會根據(jù)id + key 或者 id 為條件的方式查詢,所以這里我們可以按照id 分片即可
分512張表(實際場景具體分多少表還得根據(jù)字段增加的頻次而定)
分表后表名為kv_000 ~ kv_511
id % 512 = 1 .... 分到 kv_001,
id % 512 = 2 .... 分到 kv_002
依次類推!
水平分表相對比較容易,后面會講到基于mybatis插件實現(xiàn)方案
場景:以下我們基于博客文章表分庫場景來分析
目標:
表結(jié)構(gòu)如下(節(jié)選部分字段):
按照user_id sharding
假如分1024個庫,按照user_id % 1024 hash
user_id % 1024 = 1 分到db_001庫
user_id % 1024 = 2 分到db_002庫
依次類推
目前是2個節(jié)點,假如后期達到瓶頸,我們可以增加至4個節(jié)點
最多可以增加只1024個節(jié)點,性能線性增長
對于水平分表/分庫后,非shardingKey查詢首先得考慮到
基于mybatis分庫分表,一般常用的一種是基于spring AOP方式, 另外一種基于mybatis插件。其實兩種方式思路差不多。
為了比較直觀解決這個問題,我分別在Executor 和StatementHandler階段2個攔截器
實現(xiàn)動態(tài)數(shù)據(jù)源獲取接口
測試結(jié)果如下
由此可知,我們需要在Executor階段 切換數(shù)據(jù)源
對于分庫:
原始sql:
目標sql:
其中定義了三個注解
@useMaster 是否強制讀主
@shardingBy 分片標識
@DB 定義邏輯表名 庫名以及分片策略
1)編寫entity
Insert
select
以上順利實現(xiàn)mysql分庫,同樣的道理實現(xiàn)同時分庫分表也很容易實現(xiàn)。
此插件具體實現(xiàn)方案已開源:
目錄如下:
mysql分庫分表,首先得找到瓶頸在哪里(IO or CPU),是分庫還是分表,分多少?不能為了分庫分表而拆分。
原則上是盡量先垂直拆分 后 水平拆分。
以上基于mybatis插件分庫分表是一種實現(xiàn)思路,還有很多不完善的地方,
例如:
mysql對數(shù)據(jù)庫和表的大小都沒有做限制,mysql是一個軟件,每一個表都是一個獨立的文件,大小要看具體操作系統(tǒng)對單個文件的限制。因此,很大,一般不需要管它 。
mysql自5.1以后支持分區(qū)表,語法同Oracle類似
分區(qū)表類型有range、list、hash、key等幾種,我給一個range分區(qū)的例子吧
CREATE TABLE employees (
id INT NOT NULL,
fname VARCHAR(30),
lname VARCHAR(30),
hired DATE NOT NULL DEFAULT '1970-01-01',
separated DATE NOT NULL DEFAULT '9999-12-31',
job_code INT NOT NULL,
store_id INT NOT NULL
)
PARTITION BY RANGE (store_id) (
PARTITION p0 VALUES LESS THAN (6),
PARTITION p1 VALUES LESS THAN (11),
PARTITION p2 VALUES LESS THAN (16),
PARTITION p3 VALUES LESS THAN (21)
);