數據庫 之 Mysql的表分區

把表分區,可是還在同一臺服務器上,
html

分區是將數據分紅多個位置上,分紅多張表,實際是一張邏輯表(是虛表),被分紅了多張表,可是管理的時候能夠按照管理一張表的時候管理。前端

分區在邏輯上是同一張表,分表的話,每一張表是獨立的node

如下是三種常見的分區方法:mysql

能夠按range(範圍)切分,如1--10萬行或者時間範圍sql

按hash值切分:取模shell

按list(列表)來切分:如華東片區或者華北片區數據庫

分區相關選項查看以下,分區要是主鍵或者是主鍵的組成部分後端

MariaDB [(none)]> help create table;中的選項partition_options就是分區的選項,partition_definition爲分區的選項數組

例子服務器

例一:根據範圍(值大小)分區

如下語句表示一張students表建立成三個分區

通常從最小的數值開始定義,這裏有個默認的內建變量maxvalue,爲該表的最大值

MariaDB [sunny]> create table testpartition (id int,name varchar(100),age tinyint unsigned not null,gender enum('F','M')) partition by range(age)(partition youngman values less than (40),partition middleman values less than (60),partition oldman values less than maxvalue);

用desc查看錶的結構爲一張表

MariaDB [sunny]> desc testpartition;

在shell命令執行

[root@node71 mysql]#cd /var/lib/mysql/sunny

能夠看到對於表testpartition有三個單獨的表空間,即三個testpartition.*ibd的文件,可是表結構只有一個,即testpartition.frm 

對shell命令下,生成一組隨機值,插入testpartition表裏

定義gender數組

[root@node71 sunny]#gender=('F' 'M')

定義數組

插入1000行數據,注意外部使用雙引號,sql語句內使用單引號

[root@node71 sunny]#for i in {1..1000};do mysql -uroot -pPass1234 -e "insert into sunny.testpartition values ($i,'stud$i',$[$RANDOM%80+18],'${gender[$RANDOM%2]}');";done;

此時,在sunny.testpartition生成1000條記錄

經過這個例子,咱們能夠得出結論是,雖然咱們經過範圍進行了表切分,可是咱們是對同一張表進行操做。可是這1000條記錄是被分割到不一樣的表空間裏進行存儲

驗證,以下命令,能夠看到 testpartition#P#middleman.ibd,testpartition#P#oldman.ibd和testpartition#P#youngman.ibd已經有大小

[root@node71 sunny]#ll /var/lib/mysql/sunny -h

例二:根據id值hash後進行分區

注意,要指定分區數量,如如下partitions 5表示對5進行取模,即分紅5個區,注意hash字段的類型,字符類型如char或者varchar不能被hash,由於須要填充多餘的類型,這樣的字段不能被hash

MariaDB [sunny]> create table hashpartition (id int,name varchar(100) not null,age tinyint unsigned,gender enum ('F','M')) partition by hash(id) partitions 5;

在路徑/var/lib/mysql/sunny下生成5個表空間

 hashpartition#P#p0.ibd -- hashpartition#P#p4.ibd 

例三:根據列表劃分

假設表listpartition有一個字段majorid,有九個值,爲1--9,根據majorid進行列表分區

MariaDB [sunny]> create table listpartition (id int,name varchar(100) not null,age tinyint unsigned,gender enum ('F','M'),majorid tinyint unsigned not null) partition by list(majorid) (partition p0 values in (1,4,7),partition p1 values in (2,5,8),partition p2 values in (3,6,9));

那麼majorid 爲1,4,7三個值的數據會被分配到listpartition#P#p0.ibd裏

majorid 爲2,5,8三個值的數據會被分配到listpartition#P#p1.ibd裏

majorid 爲3,6,9三個值的數據會被分配到listpartition#P#p2.ibd裏

到此,表分區介紹完成。


若是表分區還不能解決性能的問題,建議考慮分表或者是分庫

分庫的緣由

服務器面臨大量寫操做而沒法負載,解決方案以下

1.分庫:如用戶信息放在一個庫上,購物信息放在另外一個庫上

2.分庫不能解決的話,就經過路由設備,將大量的寫請求分散到後端的服務器上,將同一個用戶的信息都發到同一服務器上,可使得同一用戶快速查看到全部的訂單。

節點級的的冗餘:每個主機後端有多個從服務器,用來分散讀操做,下降壓力,所以,每個主服務器就是一個集羣。當主服務器異常時,後端的從服務器直接選舉出新的主服務器

數據級的冗餘:當用戶請求到來時,每個節點上作數據存放的槽,如每一個節點作四個槽,每個槽就是數據存放單位,每個槽都有一個id,當用戶請求過來時,對槽進行取模,將命中槽的請求發往對應的槽。注意,這裏能夠對槽進行備份,每個槽都有副本進行冗餘,副本能夠放在另外一個服務器上空閒的槽位上,當任何一個服務器異常,也不會影響數據,對槽取模能夠保證數據讀取的均衡請求。每一個槽上的數據稱爲數據片。分片能夠實現分散寫操做。分片的架構中,前端的路由設備很關鍵,在分片級別作冗餘,每個分片的副本能夠提供讀操做。可是分片技術比較複雜。正常狀況下,一個站點一般有三層:內容,業務,數據層。隨着業務規模的增長,迭代增長,修改架構。

分表的緣由

分表將大表分解成若干個實例的表,每個表是獨立可用。

當一張的數據達到幾百萬時,你查詢一次所花的時間會變多,若是有聯合查詢的話,我想有可能會死在那兒了。分表的目的就在於此,減少數據庫的負擔,縮短查詢時間。

根據我的經驗,mysql執行一個sql的過程以下:

1,接收到sql;2,把sql放到排隊隊列中 ;3,執行sql;4,返回執行結果。在這個執行過程當中最花時間在什麼地方呢?第一,是排隊等待的時間,第二,sql的執行時間。其實這二個是一回事,等待的同時,確定有sql在執行。因此咱們要縮短sql的執行時間。

mysql中有一種機制是表鎖定和行鎖定,爲何要出現這種機制,是爲了保證數據的完整性,我舉個例子來講吧,若是有二個sql都要修改同一張表的同一條數據,這個時候怎麼辦呢,是否是二個sql均可以同時修改這條數據呢?很顯然mysql對這種狀況的處理是,一種是表鎖定(myisam存儲引擎),一個是行鎖定(innodb存儲引擎)。表鎖定表示大家都不能對這張表進行操做,必須等我對錶操做完才行。行鎖定也同樣,別的sql必須等我對這條數據操做完了,才能對這條數據進行操做。若是數據太多,一次執行的時間太長,等待的時間就越長,這也是咱們爲何要分表的緣由。

過於表分區,分表,分庫的區別,建議查看博客:https://www.cnblogs.com/langtianya/p/4997768.html

更多關於表分區的內容,建議查看博客:http://blog.51yip.com/mysql/949.html

相關文章
相關標籤/搜索