專案開發中,我們的資料庫資料越來越大,隨之而來的是單個表中資料太多。以至於查詢書讀變慢,而且由於表的鎖機制導致應用操作也搜到嚴重影響,出現了資料庫效能瓶頸。
當出現這種情況時,我們可以考慮分表,即將單個資料庫表進行拆分,拆分成多個資料表,然後使用者訪問的時候,根據一定的演算法,讓使用者訪問不同的表,這樣資料分散到多個資料表中,減少了單個資料表的訪問壓力。提公升了資料庫訪問效能。
實現mysql 分表的關鍵在於:設計良好的演算法來確定"什麼時候情況下訪問什麼(哪個)表"。
下面我們先來實現乙個簡單的mysql分表演示:這裡使用merge分表法
1,建立乙個完整表儲存著所有的成員資訊
create table member(id bigint auto_increment primary key,
name varchar(20),
*** tinyint not null default '0'
)engine=myisam default charset=utf8 auto_increment=1;
加入點資料:
insert into member(id,name,***) values (1,'jacson','0');
insert into member(name,***) select name,*** from member;
第二條語句多執行幾次就有了很多資料。
2,下面我們進行分表:這裡我們分兩個表tb_member1,tb_member2
drop table if exists tb_member1;create table tb_member1(
id bigint primary key auto_increment ,
name varchar(20),
*** tinyint not null default '0'
)engine=myisam default charset=utf8 auto_increment=1 ;
drop table if exists tb_member2;
create table tb_member2(
id bigint primary key auto_increment ,
name varchar(20),
*** tinyint not null default '0'
)engine=myisam default charset=utf8 auto_increment=1 ;
//建立tb_member2也可以用下面的語句 create table tb_member2 like tb_member1;
3.建立主表tb_member
drop table if exists tb_member;create table tb_member(
id bigint primary key auto_increment ,
name varchar(20),
*** tinyint not null default '0'
)engine=merge union=(tb_member1,tb_member2) insert_method=last charset=utf8 auto_increment=1 ;
4,接下來,我們把資料分到兩個分表中去:insert into tb_member1(id,name,***) select id,name,*** from member where id%2=0;
insert into tb_member2(id,name,***) select id,name,*** from member where id%2=1;
檢視一下主表的資料:select * from tb_member;
注意:總表只是乙個外殼,訪問資料發生在乙個乙個的分表裡面。
ps:建立主表時可能會出現下面的錯誤:
error 1168 (hy000): unable to open underlying table which is differently defined
or of non-myisam type or doesn't exist
若遇到上面這種錯誤,一般從兩方面來排查:(從這兩方面一般可以解決這個問題,本人也遇到了。)
1,檢視上面的分表資料庫引擎是不是myisam.
2,檢視分表與指標的字段定義是否一致。
分表的大概過程和步驟就是這樣的,下面我們來看看分表的演算法實現:
假設現在有乙個應用系統可能會有100億的使用者量,另外乙個表一般儲存量在不超過100萬的時候基本能保持良好效能,計算下來,我們需要1萬張表,即分表為1萬個表。
我們可以設計成:user_0~user_9999
在使用者表裡面我們有唯一的標示是使用者id,我們尅設計乙個小演算法來實現使用者id與訪問表名的對應:
function gettable($id)
return 'user_'.sprintf('%d',($id >>20));
解釋一下:($id >> 20)表示將向右移位20位,(向右移動一位標示減少一半),printf('%d',$data)標示將資料按照十進位制輸出。
即id為1~1048575(2的20次冪-1)時均訪問user_0,1048576~2097152時訪問user_1,以此類推.....
function gettable($id,$bit,$seed)d',($id >> $seed));
}其中:$id為使用者id,$bit標示表字尾的位數,$seed表示要移位的位數即:單個錶能儲存的記錄條數。
這樣就可以任意分表了。
總結:其實上面我們介紹的是水平分表的實施方法,還存在另一種方法叫做:垂直分表
垂直分表:
舉例說明,在乙個部落格系統中,文章標題,作者,分類,建立時間等,是變化頻率慢,查詢次數多,而且最好有很好的實時性的資料,我們把它叫做冷資料。
而部落格的瀏覽量,回覆數等,類似的統計資訊,或者別的變化頻率比較高的資料,我們把它叫做活躍資料。
我們進行縱向分表後:
1,儲存引擎的使用不同,冷資料使用myisam 可以有更好的查詢資料。活躍資料,可以使用innodb ,可以有更好的更新速度。
2,對冷資料進行更多的從庫配置,因為更多的操作是查詢,這樣來加快查詢速度。對熱資料,可以相對有更多的主庫的橫向分表處理。
3,對於一些特殊的活躍資料,也可以考慮使用memcache ,redis之類的快取,等累計到一定量再去更新資料庫.
分表的大概過程和步驟就是這樣的,下面我們來看看分表的演算法實現:
假設現在有乙個應用系統可能會有100億的使用者量,另外乙個表一般儲存量在不超過100萬的時候基本能保持良好效能,計算下來,我們需要1萬張表,即分表為1萬個表。
我們可以設計成:user_0~user_9999
在使用者表裡面我們有唯一的標示是使用者id,我們尅設計乙個小演算法來實現使用者id與訪問表名的對應:
function gettable($id)
return 'user_'.sprintf('%d',($id >>20));
解釋一下:($id >> 20)表示將向右移位20位,(向右移動一位標示減少一半),printf('%d',$data)標示將資料按照十進位制輸出。
即id為1~1048575(2的20次冪-1)時均訪問user_0,1048576~2097152時訪問user_1,以此類推.....
function gettable($id,$bit,$seed)d',($id >> $seed));
}其中:$id為使用者id,$bit標示表字尾的位數,$seed表示要移位的位數即:單個錶能儲存的記錄條數。
這樣就可以任意分表了。
總結:其實上面我們介紹的是水平分表的實施方法,還存在另一種方法叫做:垂直分表
垂直分表:
舉例說明,在乙個部落格系統中,文章標題,作者,分類,建立時間等,是變化頻率慢,查詢次數多,而且最好有很好的實時性的資料,我們把它叫做冷資料。
而部落格的瀏覽量,回覆數等,類似的統計資訊,或者別的變化頻率比較高的資料,我們把它叫做活躍資料。
我們進行縱向分表後:
1,儲存引擎的使用不同,冷資料使用myisam 可以有更好的查詢資料。活躍資料,可以使用innodb ,可以有更好的更新速度。
2,對冷資料進行更多的從庫配置,因為更多的操作是查詢,這樣來加快查詢速度。對熱資料,可以相對有更多的主庫的橫向分表處理。
3,對於一些特殊的活躍資料,也可以考慮使用memcache ,redis之類的快取,等累計到一定量再去更新資料庫.
mysql資料庫分表
定時執行建立cisco tunnel分表 start ciscotunnelcreatejob class com.sdwan.task.ciscotunnelpartition ciscotunnelcreatejobmethod class org.springframework.schedul...
mysql表連線例項 mysql資料庫表的連線例項
一般所說的左連線,是指左,右。先說左外連線和右外連線 sql select from t1 id name 1 aaa 2 bbb sql select from t2 id age 1 20 3 30 左外連線 object object sql select from t1 left join ...
mysql資料庫 分表儲存 分表查詢
因為看到公司資料庫商家的商品是儲存在多個商品表的分表中,這裡是有 0 9 共10個分表,就突然有了疑惑,怎麼存的?查尋的時候怎麼查的?怎麼定位到這個商家的商品在某乙個分表中?這裡簡單的來記錄一下 分表是這樣的 研究完 以後終於把疑惑解開,簡單記錄一下 1 其實是儲存和查詢的時候都帶有乙個標誌來區分表...