http://blog.csdn.net/lgb934/article/details/8662956
http://www.2cto.com/database/201503/380348.html
什么是分表?
分表是將一個大表按照一定的規則分解成多張具有獨立存儲空間的實體表,我們可以稱為子表,每個表都對應三個文件,MYD數據文件,.MYI索引文件,.frm表結構文件。這些子表可以分布在同一塊磁盤上,也可以在不同的機器上。app讀寫的時候根據事先定義好的規則得到對應的子表名,然后去操作它
什么是分區?
分區和分表相似,都是按照規則分解表。不同在於分表將大表分解為若干個獨立的實體表,而分區是將數據分段划分在多個位置存放,可以是同一塊磁盤也可以在不同的機器。分區后,表面上還是一張表,但數據散列到多個位置了。app讀寫的時候操作的還是大表名字,db自動去組織分區的數據。
表分區分為水平分區和垂直分區。水平分區將表分為多個表。每個表包含的列數相同,但是行更少。例如,可以將一個包含十億行的表水平分區成 12 個表,每個小表表示特定年份內一個月或幾個月的數據。任何需要特定月份數據的查詢只需引用相應月份的表。而垂直分區則是將原始表分成多個只包含較少列的表。水平分區是最常用分區方式,后面我們以水平分區來介紹具體實現方法。
簡單一點說,分區表就是將一個大表分成若干個小表。
分區步驟:
創建分區表必須要經過下面五個步驟。
1)創建文件組
2)創建文件
3)創建分區函數
4)創建分區方案
5)創建分區表
(1)創建文件組,有兩種方案,一種是通過手動添加,另外一種就是通過SQL腳本進行添加。下面以兩種方案來說明:
方案一:創建文件組,雖然這一步我們可以省略,因為我們可以直接使用Primary文件(也就是系統主文件)。但是為了方便管理,我們還是要創建幾個文件組,這樣可以將不同的小表(不同時間段,或者不同數據表)放在不同的文件組里,既便於理解又可以提高運行速度。
打開SQL Server Management Studio,找到分區表所在的數據庫,右鍵單擊選擇“屬性”,選擇“文件組”選項,單擊下面的“添加”按鈕,添加X個文件組
方案二:通過查詢分析器SQL腳本執行
ALTER DATABASE CXFunSche ADD FILEGROUP CXFG2010
ALTER DATABASE CXFunSche ADD FILEGROUP CXFG2011
ALTER DATABASE CXFunSche ADD FILEGROUP CXFG2012
ALTER DATABASE CXFunSche ADD FILEGROUP CXFG2013
(2)創建數據庫文件
方案一:創建了文件組之后,還要再創建幾個數據庫文件。為什么要創建數據庫文件,這很好理解,因為分區的小表必須要放在硬盤上,而放在硬盤上的什么地方呢?當然是文件里啦。再說了,文件組中沒有文件,文件組還要來有啥用呢?還是在上圖的那個界面,選擇“文件”選項,然后添加幾個文件。在添加文件的時候要注意以下幾點:
1、不要忘記將不同的文件放在文件組中。當然一個文件組中也可以包含多個不同的文件。
2、如果可以的話,將不同的文件放在不同的硬盤分區里,最好是放在不同的獨立硬盤里。要知道IQ的速度往往是影響SQL Server運行速度的重要條件之一。將不同的文件放在不同的硬盤上,可以加快SQL Server的運行速度。
方案二:通過查詢分析器SQL腳本執行
ALTER DATABASE CXFunSche ADD FILE ( NAME = N'SellLogDetail2010', FILENAME = N'D:\program files\Programming Software\SQL Server 2005\MSSQL.1\MSSQL\DATA\SellLogDetail2010.ndf' , SIZE = 3072KB ,FILEGROWTH = 1024KB ) TO FILEGROUP CXFG2010
ALTER DATABASE CXFunSche ADD FILE ( NAME = N'SellLogDetail201102', FILENAME = N'D:\program files\Programming Software\SQL Server 2005\MSSQL.1\MSSQL\DATA\SellLogDetail201102.ndf' , SIZE = 3072KB , FILEGROWTH = 1024KB ) TO FILEGROUP CXFG2010
ALTER DATABASE CXFunSche ADD FILE ( NAME = N'SellLogDetail201104', FILENAME = N'D:\program files\Programming Software\SQL Server 2005\MSSQL.1\MSSQL\DATA\SellLogDetail201104.ndf' , SIZE = 3072KB , FILEGROWTH = 1024KB ) TO FILEGROUP CXFG2011
ALTER DATABASE CXFunSche ADD FILE ( NAME = N'SellLogDetail201106', FILENAME = N'D:\program files\Programming Software\SQL Server 2005\MSSQL.1\MSSQL\DATA\SellLogDetail201106.ndf' , SIZE = 3072KB , FILEGROWTH = 1024KB ) TO FILEGROUP CXFG2011
ALTER DATABASE CXFunSche ADD FILE ( NAME = N'SellLogDetail201108', FILENAME = N'D:\program files\Programming Software\SQL Server 2005\MSSQL.1\MSSQL\DATA\SellLogDetail201108.ndf' , SIZE = 3072KB , FILEGROWTH = 1024KB ) TO FILEGROUP CXFG2011
ALTER DATABASE CXFunSche ADD FILE ( NAME = N'SellLogDetail201110', FILENAME = N'D:\program files\Programming Software\SQL Server 2005\MSSQL.1\MSSQL\DATA\SellLogDetail201110.ndf' , SIZE = 3072KB , FILEGROWTH = 1024KB ) TO FILEGROUP CXFG2011
ALTER DATABASE CXFunSche ADD FILE ( NAME = N'SellLogDetail201112', FILENAME = N'D:\program files\Programming Software\SQL Server 2005\MSSQL.1\MSSQL\DATA\SellLogDetail201112.ndf' , SIZE = 3072KB , FILEGROWTH = 1024KB ) TO FILEGROUP CXFG2011
ALTER DATABASE CXFunSche ADD FILE ( NAME = N'SellLogDetail201202', FILENAME = N'D:\program files\Programming Software\SQL Server 2005\MSSQL.1\MSSQL\DATA\SellLogDetail201202.ndf' , SIZE = 3072KB , FILEGROWTH = 1024KB ) TO FILEGROUP CXFG2012
mysql分區的幾種方式
Range:
1
2
3
4
5
6
7
8
9
10
|
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:
1
2
3
4
5
6
7
|
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:
1
2
3
4
5
|
create
table
hash(
a
int
(11),
b datetime
)partition
by
hash (
YEAR
(b)
partitions 4;
|
Key:
1
2
3
4
5
|
create
table
t_key(
a
int
(11),
b datetime)
partition
by
key
(b)
partitions 4;
|
分區管理
新增分區
1
2
|
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
1
2
3
4
5
6
7
8
9
|
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
)
);
|
分表的幾種方式:
1、mysql集群
它並不是分表,但起到了和分表相同的作用。集群可分擔數據庫的操作次數,將任務分擔到多台數據庫上。集群可以讀寫分離,減少讀寫壓力。從而提升數據庫性能。
2、自定義規則分表
大表可以按照業務的規則來分解為多個子表。通常為以下幾種類型,也可自己定義規則。
1
2
3
4
5
|
Range(范圍)–這種模式允許將數據划分不同范圍。例如可以將一個表通過年份划分成若干個分區。
Hash(哈希)–這中模式允許通過對表的一個或多個列的Hash
Key
進行計算,最后通過這個Hash碼不同數值對應的數據區域進行分區。例如可以建立一個對表主鍵進行分區的表。
Key
(鍵值)-上面Hash模式的一種延伸,這里的Hash
Key
是MySQL系統產生的。
List(預定義列表)–這種模式允許系統通過預定義的列表的值來對數據進行分割。
Composite(復合模式) –以上模式的組合使用
|
下面以Range簡單介紹下如何分表(按照年份表)。
假設表結構有4個字段:自增id,姓名,存款金額,存款日期
把存款日期作為規則分表,分別創建幾個表
2011年:account_2011
2012年:account_2012
……
2015年:account_2015
app在讀寫的時候根據日期來查找對應的表名,需要手動來判定。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
var getTableName =
function
() {
var data = {
name
:
'tom'
,
money: 2800.00,
date
:
'201410013059'
};
var tablename =
'account_'
;
var
year
= parseInt(data.
date
.
substring
(0, 4));
if (
year
< 2012) {
tablename += 2011; // account_2011
}
else
if (
year
< 2013) {
tablename += 2012; // account_2012
}
else
if (
year
< 2014) {
tablename += 2013; // account_2013
}
else
if (
year
< 2015) {
tablename += 2014; // account_2014
}
else
{
tablename += 2015; // account_2015
}
return
tablename;
}
|
3、利用merge存儲引擎來實現分表
merge分表,分為主表和子表,主表類似於一個殼子,邏輯上封裝了子表,實際上數據都是存儲在子表中的。
我們可以通過主表插入和查詢數據,如果清楚分表規律,也可以直接操作子表。
子表2011年
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
CREATE
TABLE
`account_2011` (
`id`
int
(11)
NOT
NULL
AUTO_INCREMENT ,
`
name
`
varchar
(50)
CHARACTER
SET
utf8
COLLATE
utf8_general_ci
NULL
DEFAULT
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年
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
CREATE
TABLE
`account_2012` (
`id`
int
(11)
NOT
NULL
AUTO_INCREMENT ,
`
name
`
varchar
(50)
CHARACTER
SET
utf8
COLLATE
utf8_general_ci
NULL
DEFAULT
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
;
|
主表,所有年
1
2
3
4
5
6
7
8
9
10
11
12
13
|
CREATE
TABLE
`account_all` (
`id`
int
(11)
NOT
NULL
AUTO_INCREMENT ,
`
name
`
varchar
(50)
CHARACTER
SET
utf8
COLLATE
utf8_general_ci
NULL
DEFAULT
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
;
|
創建主表的時候有個INSERT_METHOD,指明插入方式,取值可以是:0 不允許插入;FIRST 插入到UNION中的第一個表; LAST 插入到UNION中的最后一個表。
通過主表查詢的時候,相當於將所有子表合在一起查詢。這樣並不能體現分表的優勢,建議還是查詢子表。