MySQL 分表和分區

1.爲何須要分表和分區mysql

  在開發的過程當中,常常會遇到大表的狀況,所謂的大表是指存儲了百萬級乃至千萬級條記錄的表。這樣的表過於龐大,致使數據庫在查詢和插入的時候耗時太長,若是涉及聯合查詢的狀況,性能更加糟糕。分表和分區的目的就是減小數據庫的負擔,提升數據庫的效率,就是提升表的增刪改查。sql

 

2.分表數據庫

  分表是講一個大表按照必定的規則分解成多張具備獨立存儲空間的實體表,咱們能夠稱爲子表,每一個表都對應三個文件,MYD數據文件,.MYI索引文件,.frm表結構文件。這些子表能夠分佈在同一塊磁盤上,也能夠在不一樣的機器。讀寫的時候根據事先定義好的規則獲得對應的子表名,而後去操做它。併發

 

3.分區less

  分區和分表類似,都是按照規則分解表。不一樣在於分表將大表分解爲若干個獨立的實體表,而分區是將數據分段劃分在多個位置存放,能夠是同一塊磁盤,也能夠在不一樣的機器。分區後,表面上是一張表,但數據散列到多個位置了。讀寫的時候操做的仍是大表的名字,db自動去組織分區的數據。高併發

 

4.分表和分區聯繫性能

  都能提升mysql的性能,在高併發狀態下都有一個良好的表現。索引

·  分表和分區不矛盾,能夠相互配合的,對於那些大訪問量,而且表數據較多的表,咱們能夠採起分表和分區結合的方式(若是merge這種分表方式,不能和分區配合的話,能夠用其餘的分表),訪問量不大,可是表數據不少的表,能夠採起分區的方式。ci

  分表技術是比較麻煩的,須要手動建立子表,服務端讀寫的時候須要計算表名。採用merge好一些,但也要建立子表和配置子表之間的union關係。開發

  表分區相對於分表,操做方便,不須要建立子表。

 

5.分表的幾種方式

  mysql集羣

  它並非分表,但起到了和分表相同的做用。集羣能夠分擔數據庫的操做次數,將任務分擔到多臺數據庫上。集羣能夠讀寫分離,減小讀寫壓力。從而提高數據庫性能。

  自定義規則分表

  大表能夠按照業務規則來分解爲多個子表。一般爲一下幾種類型,也能夠本身定義規則。

  Range(範圍):這種模式容許將數據庫劃分不一樣範圍。例如經過年份劃分。

  Hash(哈希):這種模式容許經過對錶的一個或多個列的Hash Key進行計算,最後經過這個Hash碼不一樣數值對應的數據區域進行分區。例如能夠創建一個對錶主鍵進行分區的表。

  Key(鍵值):上面Hash模式的一種延伸,這裏的Hash Key是MySQL系統產生的。

  List(預約義列表):這中模式容許系統經過預約義的列表的值來對數據進行分割。

  Composite(複合模式):以上模式的組合使用。

 

  分表與分區規則同樣

  1.Range分表:

  設:表有四個字段 自增id 姓名 存款金額 存款日期

  存款日期最爲規則分表,分別建立幾個表

  2011年:account_2011

  2012年:account_2012

  ...

  2017年:account_2017

  讀寫的時候根據日期來查找對應的表名,須要手動來判斷

  

  2.利用merge存儲引擎來實現分表

  merge分表分爲主表和子表,主表相似一個殼子,邏輯上封裝了子表,實際上數據都是存儲在子表中的。

  咱們能夠經過主表插入和查詢數據,若是清楚分表規律,也能夠直接操做子表。

  子表2011年

  CREATE TABLE `account_2011` (

  `id`  int(11) NOT NULL AUTO_INCREMENT ,

         `name`  varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFA  ULT NULL ,

  `money`  float NOT NULL ,

  `tradeDate`  datetime NOT NULL

  PRIMARY KEY (`id`))

  ENGINE=MyISAM

  DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci

  AUTO_INCREMENT=2

  CHECKSUM=0

  ROW_FORMAT=DYNAMIC

  DELAY_KEY_WRITE=0;

 

  子表2012年

  CREATE TABLE `account_2012` (

  `id`  int(11) NOT NULL AUTO_INCREMENT ,

     `name`  varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFA  ULT NULL ,

  `money`  float NOT NULL ,

  `tradeDate`  datetime NOT NULL

  PRIMARY KEY (`id`))

  ENGINE=MyISAM

  DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci

  AUTO_INCREMENT=2

  CHECKSUM=0

  ROW_FORMAT=DYNAMIC

  DELAY_KEY_WRITE=0;

  

  主表 全部年份

  CREATE TABLE `account_all` (

  `id`  int(11) NOT NULL AUTO_INCREMENT ,

     `name`  varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFA  ULT NULL ,

  `money`  float NOT NULL ,

  `tradeDate`  datetime NOT NULL

  PRIMARY KEY (`id`))

  ENGINE=MRG_MYISAM

  DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci

  UNION=(`account_2011`,`account_2012`)

  INSERT_METHOD=LAST

  ROW_FORMAT=DYNAMIC;

  建立主表的時候有個INERT_METHOD,指明插入的方式,取值能夠是:0不容許插      入;FIRST插入到UNION中的第一個表;LAST插入到UNION的最後一個表。

       經過主表查詢的時候,至關於將全部子表合在一塊兒查詢。這樣並不能體現分表的優       勢,建議仍是查詢子表、

 

  分區的幾種方式:

  Range:

       create table range(

  id int(11),

  money int(11) unsigned not null,

  date datetime

  )partition by range(year(date))(

  partition p2007 values less than (2008),

  partition p2008 values less than (2009),

  partition p2009 values less than (2010)

partition p2010 values less than maxvalue);

 

  List:

       create table list(

  a int(11),

  b int(11)

  )(partition by list (b)

  partition p0 values in (1,3,5,7,9),

  partition p1 values in (2,4,6,8,0)

 );

  

  Hash:

       create table hash(

  a int(11),

  b datetime

  )partition by hash (YEAR(b)

  partitions 4;

 

  Key:

       create table t_key(

  a int(11),

  b datetime)

  partition by key (b)

  partitions 4;

 

  分區管理:

  新增分區:

  ALTER TABLE sale_data

  ADD PARTITION (PARTITION p201010 VALUES LESS THAN (201011));

  

  刪除分區:

  一旦刪除了一個分區,也同時刪除該分區全部的數據。

  ALTER TABLE sale_data DROP PARTITION p201010

  

  分區的合併:

  下面的SQL,將p201001 - p201009 合併爲3個分區p2010Q1 - p2010Q3

  ALTER TABLE sale_data

  REORGANIZE PARTITION p201001,p201002,p201003,

  p201004,p201005,p201006,

  p201007,p201008,p201009 INTO

       (

       PARTITION p2010Q1 VALUES LESS THAN (201004),

       PARTITION p2010Q2 VALUES LESS THAN (201007),

       PARTITION p2010Q3 VALUES LESS THAN (201010)

);

相關文章
相關標籤/搜索