mysql的分區和分表
分區
分區就是把一個數據表的文件和索引分散存儲在不同的物理文件中。
mysql支持的分區類型包括Range、List、Hash、Key,其中Range比較常用:
RANGE分區:基於屬於一個給定連續區間的列值,把多行分配給分區。
LIST分區:類似於按RANGE分區,區別在於LIST分區是基於列值匹配一個離散值集合中的某個值來進行選擇。
HASH分區:基於用戶定義的表達式的返回值來進行選擇的分區,該表達式使用將要插入到表中的這些行的列值進行計算。這個函數可以包含MySQL 中有效的、產生非負整數值的任何表達式。
KEY分區:類似於按HASH分區,區別在於KEY分區只支持計算一列或多列,且MySQL伺服器提供其自身的哈希函數。必須有一列或多列包含整數值。
案例:
建立一個user 表 以id進行分區 id 小於10的在user_1分區id小於20的在user_2分區
create table user(
id int not null auto_increment,
username varchar(10),
primary key(id)
)engine = innodb charset=utf8
partition by range (id)(
partition user_1 values less than (10),
partition user_2 values less than (20)
);
建立後添加分區:
maxvalue 表示最大值 這樣大於等於20的id 都出存儲在user_3分區
alter table user add partition(
partition user_3 values less than maxvalue
);
刪除分區:
alter table user drop partition user_3;
現在打開mysql的數據目錄
可以看見多了user#P#user_1.ibd 和user#P#user_2.ibd 這兩個文件
如果表使用的存儲引擎是MyISAM類型,就是:
user#P#user_1.MYD,user#P#user_1.MYI和user#P#user_2.MYD,user#P#user_2.MYI
分區模式詳解:
* Range(範圍) – 這種模式允許DBA將數據劃分不同範圍。例如DBA可以將一個表通過年份劃分成三個分區,80年代(1980's)的數據,90年代(1990's)的數據以及任何在2000年(包括2000年)後的數據。
CREATE TABLE users (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
usersname VARCHAR(30) NOT NULL DEFAULT '',
email VARCHAR(30) NOT NULL DEFAULT ''
)
PARTITION BY RANGE (id) (
PARTITION p0 VALUES LESS THAN (3000000),
PARTITION p1 VALUES LESS THAN (6000000),
PARTITION p2 VALUES LESS THAN (9000000),
PARTITION p3 VALUES LESS THAN MAXVALUE
);
在這裡,將用戶表分成4個分區,以每300萬條記錄為界限,每個分區都有自己獨立的數據、索引文件的存放目錄。
還可以將這些分區所在的物理磁碟分開完全獨立,可以提高磁碟IO吞吐量。
如果你也想成為程式設計師,想要快速掌握編程,趕緊關注小編加入學習企鵝圈子吧!
裡面有資深專業軟體開發工程師,在線解答你的所有疑惑~程式語言入門「so easy」
資料包含:編程入門、遊戲編程、課程設計等。
免費學習書籍:
免費學習資料:
CREATE TABLE users (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
usersname VARCHAR(30) NOT NULL DEFAULT '',
email VARCHAR(30) NOT NULL DEFAULT ''
)
PARTITION BY RANGE (id) (
PARTITION p0 VALUES LESS THAN (3000000)
DATA DIRECTORY = '/data0/data'
INDEX DIRECTORY = '/data0/index',
PARTITION p1 VALUES LESS THAN (6000000)
DATA DIRECTORY = '/data1/data'
INDEX DIRECTORY = '/data1/index',
PARTITION p2 VALUES LESS THAN (9000000)
DATA DIRECTORY = '/data2/data'
INDEX DIRECTORY = '/data2/index',
PARTITION p3 VALUES LESS THAN MAXVALUE
DATA DIRECTORY = '/data3/data'
INDEX DIRECTORY = '/data3/index'
);
* List(預定義列表) – 這種模式允許系統通過DBA定義的列表的值所對應的行數據進行分割。例如:DBA根據用戶的類型進行分區。
CREATE TABLE user (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(30) NOT NULL DEFAULT '' ,
user_type int not null
)
PARTITION BY LIST (user_type ) (
PARTITION p0 VALUES IN (0,4,8,12) ,
PARTITION p1 VALUES IN (1,5,9,13) ,
PARTITION p2 VALUES IN (2,6,10,14),
PARTITION p3 VALUES IN (3,7,11,15)
);
分成4個區,同樣可以將分區設置的獨立的磁碟中。
* Key(鍵值)
CREATE TABLE user (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(30) NOT NULL DEFAULT '',
email VARCHAR(30) NOT NULL DEFAULT ''
)
PARTITION BY KEY (id) PARTITIONS 4 (
PARTITION p0,
PARTITION p1,
PARTITION p2,
PARTITION p3
);
* Hash(哈希)
CREATE TABLE user (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(30) NOT NULL DEFAULT '',
email VARCHAR(30) NOT NULL DEFAULT ''
)
PARTITION BY HASH (id) PARTITIONS 4 (
PARTITION p0 ,
PARTITION p1,
PARTITION p2,
PARTITION p3
);
分表
分表和分區類似,區別是,分區是把一個邏輯表文件分成幾個物理文件後進行存儲,而分表則是把原先的一個表分成幾個表。進行分表查詢時可以通過union或者視圖。
分表又分垂直分割和水平分割,其中水平分分割最為常用。水平分割通常是指切分到另外一個資料庫或表中。例如對於一個會員表,按對3的模進行分割:
table = id%3
如果id%3 = 0 則將用戶數據放入到user_0表中,如id%3=1就放入user_1表中,依次類推。
在這裡有個問題,這個uid應該是所有會員按序增長的,可他是怎麼得到的呢?使用auto_increment是不行的,這樣就用到序列了。
對於一些流量統計系統,其數據量比較大,並且對過往數據的關注度不高,這時按年、月、日進行分表,將每日統計信息放到一個以日期命名的表中;或者按照增量進行分表,如每個表100萬數據,超過100萬就放入第二個表。還可以按Hash進行分表,但是按日期和取模餘數分表最為常見,也容易擴展。
分表後可能會遇到新的問題,那就是查詢,分頁和統計。通用的方法是在程序中進行處理,輔助視圖。