真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

mysql的分片怎么寫 2021年9月18日國難日結(jié)婚

mysql 什么時(shí)候分區(qū) 什么時(shí)候分表

一,什么是mysql分表,分區(qū)

成都創(chuàng)新互聯(lián)是創(chuàng)新、創(chuàng)意、研發(fā)型一體的綜合型網(wǎng)站建設(shè)公司,自成立以來公司不斷探索創(chuàng)新,始終堅(jiān)持為客戶提供滿意周到的服務(wù),在本地打下了良好的口碑,在過去的十多年時(shí)間我們累計(jì)服務(wù)了上千家以及全國政企客戶,如成都石牌坊等企業(yè)單位,完善的項(xiàng)目管理流程,嚴(yán)格把控項(xiàng)目進(jìn)度與質(zhì)量監(jiān)控加上過硬的技術(shù)實(shí)力獲得客戶的一致贊賞。

什么是分表,從表面意思上看呢,就是把一張表分成N多個(gè)小表,具體請(qǐng)看mysql分表的3種方法

什么是分區(qū),分區(qū)呢就是把一張表的數(shù)據(jù)分成N多個(gè)區(qū)塊,這些區(qū)塊可以在同一個(gè)磁盤上,也可以在不同的磁盤上

一,先說一下為什么要分表

當(dāng)一張的數(shù)據(jù)達(dá)到幾百萬時(shí),你查詢一次所花的時(shí)間會(huì)變多,如果有聯(lián)合查詢的話,我想有可能會(huì)死在那兒了。分表的目的就在于此,減小數(shù)據(jù)庫的負(fù)擔(dān),縮短查詢時(shí)間。

根據(jù)個(gè)人經(jīng)驗(yàn),mysql執(zhí)行一個(gè)sql的過程如下:

1,接收到sql;2,把sql放到排隊(duì)隊(duì)列中 ;3,執(zhí)行sql;4,返回執(zhí)行結(jié)果。在這個(gè)執(zhí)行過程中最花時(shí)間在什么地方呢?第一,是排隊(duì)等待的時(shí)間,第二,sql的執(zhí)行時(shí)間。其實(shí)這二個(gè)是一回事,等待的同時(shí),肯定有sql在執(zhí)行。所以我們要縮短sql的執(zhí)行時(shí)間。

mysql中有一種機(jī)制是表鎖定和行鎖定,為什么要出現(xiàn)這種機(jī)制,是為了保證數(shù)據(jù)的完整性,我舉個(gè)例子來說吧,如果有二個(gè)sql都要修改同一張表的同一條數(shù)據(jù),這個(gè)時(shí)候怎么辦呢,是不是二個(gè)sql都可以同時(shí)修改這條數(shù)據(jù)呢?很顯然mysql對(duì)這種情況的處理是,一種是表鎖定(myisam存儲(chǔ)引擎),一個(gè)是行鎖定(innodb存儲(chǔ)引擎)。表鎖定表示你們都不能對(duì)這張表進(jìn)行操作,必須等我對(duì)表操作完才行。行鎖定也一樣,別的sql必須等我對(duì)這條數(shù)據(jù)操作完了,才能對(duì)這條數(shù)據(jù)進(jìn)行操作。如果數(shù)據(jù)太多,一次執(zhí)行的時(shí)間太長(zhǎng),等待的時(shí)間就越長(zhǎng),這也是我們?yōu)槭裁匆直淼脑颉?/p>

二,分表

1,做mysql集群,例如:利用mysql cluster ,mysql proxy,mysql replication,drdb等等

有人會(huì)問mysql集群,根分表有什么關(guān)系嗎?雖然它不是實(shí)際意義上的分表,但是它啟到了分表的作用,做集群的意義是什么呢?為一個(gè)數(shù)據(jù)庫減輕負(fù)擔(dān),說白了就是減少sql排隊(duì)隊(duì)列中的sql的數(shù)量,舉個(gè)例子:有10個(gè)sql請(qǐng)求,如果放在一個(gè)數(shù)據(jù)庫服務(wù)器的排隊(duì)隊(duì)列中,他要等很長(zhǎng)時(shí)間,如果把這10個(gè)sql請(qǐng)求,分配到5個(gè)數(shù)據(jù)庫服務(wù)器的排隊(duì)隊(duì)列中,一個(gè)數(shù)據(jù)庫服務(wù)器的隊(duì)列中只有2個(gè),這樣等待時(shí)間是不是大大的縮短了呢?這已經(jīng)很明顯了。所以我把它列到了分表的范圍以內(nèi),我做過一些mysql的集群:

linux mysql proxy 的安裝,配置,以及讀寫分離

mysql replication 互為主從的安裝及配置,以及數(shù)據(jù)同步

優(yōu)點(diǎn):擴(kuò)展性好,沒有多個(gè)分表后的復(fù)雜操作(php代碼)

缺點(diǎn):?jiǎn)蝹€(gè)表的數(shù)據(jù)量還是沒有變,一次操作所花的時(shí)間還是那么多,硬件開銷大。

2,預(yù)先估計(jì)會(huì)出現(xiàn)大數(shù)據(jù)量并且訪問頻繁的表,將其分為若干個(gè)表

這種預(yù)估大差不差的,論壇里面發(fā)表帖子的表,時(shí)間長(zhǎng)了這張表肯定很大,幾十萬,幾百萬都有可能。 聊天室里面信息表,幾十個(gè)人在一起一聊一個(gè)晚上,時(shí)間長(zhǎng)了,這張表的數(shù)據(jù)肯定很大。像這樣的情況很多。所以這種能預(yù)估出來的大數(shù)據(jù)量表,我們就事先分出個(gè)N個(gè)表,這個(gè)N是多少,根據(jù)實(shí)際情況而定。以聊天信息表為例:

我事先建100個(gè)這樣的表,message_00,message_01,message_02..........message_98,message_99.然后根據(jù)用戶的ID來判斷這個(gè)用戶的聊天信息放到哪張表里面,你可以用hash的方式來獲得,可以用求余的方式來獲得,方法很多,各人想各人的吧。下面用hash的方法來獲得表名:

查看復(fù)制打印?

?php

function get_hash_table($table,$userid) {

$str = crc32($userid);

if($str0){

$hash = "0".substr(abs($str), 0, 1);

}else{

$hash = substr($str, 0, 2);

}

return $table."_".$hash;

}

echo get_hash_table('message','user18991'); //結(jié)果為message_10

echo get_hash_table('message','user34523'); //結(jié)果為message_13

?

說明一下,上面的這個(gè)方法,告訴我們user18991這個(gè)用戶的消息都記錄在message_10這張表里,user34523這個(gè)用戶的消息都記錄在message_13這張表里,讀取的時(shí)候,只要從各自的表中讀取就行了。

優(yōu)點(diǎn):避免一張表出現(xiàn)幾百萬條數(shù)據(jù),縮短了一條sql的執(zhí)行時(shí)間

缺點(diǎn):當(dāng)一種規(guī)則確定時(shí),打破這條規(guī)則會(huì)很麻煩,上面的例子中我用的hash算法是crc32,如果我現(xiàn)在不想用這個(gè)算法了,改用md5后,會(huì)使同一個(gè)用戶的消息被存儲(chǔ)到不同的表中,這樣數(shù)據(jù)亂套了。擴(kuò)展性很差。

3,利用merge存儲(chǔ)引擎來實(shí)現(xiàn)分表

我覺得這種方法比較適合,那些沒有事先考慮,而已經(jīng)出現(xiàn)了得,數(shù)據(jù)查詢慢的情況。這個(gè)時(shí)候如果要把已有的大數(shù)據(jù)量表分開比較痛苦,最痛苦的事就是改代碼,因?yàn)槌绦蚶锩娴膕ql語句已經(jīng)寫好了,現(xiàn)在一張表要分成幾十張表,甚至上百張表,這樣sql語句是不是要重寫呢?舉個(gè)例子,我很喜歡舉子

mysqlshow engines;的時(shí)候你會(huì)發(fā)現(xiàn)mrg_myisam其實(shí)就是merge。

查看復(fù)制打印?

mysql CREATE TABLE IF NOT EXISTS `user1` (

- `id` int(11) NOT NULL AUTO_INCREMENT,

- `name` varchar(50) DEFAULT NULL,

- `sex` int(1) NOT NULL DEFAULT '0',

- PRIMARY KEY (`id`)

- ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

Query OK, 0 rows affected (0.05 sec)

mysql CREATE TABLE IF NOT EXISTS `user2` (

- `id` int(11) NOT NULL AUTO_INCREMENT,

- `name` varchar(50) DEFAULT NULL,

- `sex` int(1) NOT NULL DEFAULT '0',

- PRIMARY KEY (`id`)

- ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

Query OK, 0 rows affected (0.01 sec)

mysql INSERT INTO `user1` (`name`, `sex`) VALUES('張映', 0);

Query OK, 1 row affected (0.00 sec)

mysql INSERT INTO `user2` (`name`, `sex`) VALUES('tank', 1);

Query OK, 1 row affected (0.00 sec)

mysql CREATE TABLE IF NOT EXISTS `alluser` (

- `id` int(11) NOT NULL AUTO_INCREMENT,

- `name` varchar(50) DEFAULT NULL,

- `sex` int(1) NOT NULL DEFAULT '0',

- INDEX(id)

- ) TYPE=MERGE UNION=(user1,user2) INSERT_METHOD=LAST AUTO_INCREMENT=1 ;

Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql select id,name,sex from alluser;

+----+--------+-----+

| id | name | sex |

+----+--------+-----+

| 1 | 張映 | 0 |

| 1 | tank | 1 |

+----+--------+-----+

2 rows in set (0.00 sec)

mysql INSERT INTO `alluser` (`name`, `sex`) VALUES('tank2', 0);

Query OK, 1 row affected (0.00 sec)

mysql select id,name,sex from user2

- ;

+----+-------+-----+

| id | name | sex |

+----+-------+-----+

| 1 | tank | 1 |

| 2 | tank2 | 0 |

+----+-------+-----+

2 rows in set (0.00 sec)

從上面的操作中,我不知道你有沒有發(fā)現(xiàn)點(diǎn)什么?假如我有一張用戶表user,有50W條數(shù)據(jù),現(xiàn)在要拆成二張表user1和user2,每張表25W條數(shù)據(jù),

INSERT INTO user1(user1.id,user1.name,user1.sex)SELECT (user.id,user.name,user.sex)FROM user where user.id = 250000

INSERT INTO user2(user2.id,user2.name,user2.sex)SELECT (user.id,user.name,user.sex)FROM user where user.id 250000

這樣我就成功的將一張user表,分成了二個(gè)表,這個(gè)時(shí)候有一個(gè)問題,代碼中的sql語句怎么辦,以前是一張表,現(xiàn)在變成二張表了,代碼改動(dòng)很大,這樣給程序員帶來了很大的工作量,有沒有好的辦法解決這一點(diǎn)呢?辦法是把以前的user表備份一下,然后刪除掉,上面的操作中我建立了一個(gè)alluser表,只把這個(gè)alluser表的表名改成user就行了。但是,不是所有的mysql操作都能用的

a,如果你使用 alter table 來把 merge 表變?yōu)槠渌眍愋?,到底層表的映射就被丟失了。取而代之的,來自底層 myisam 表的行被復(fù)制到已更換的表中,該表隨后被指定新類型。

b,網(wǎng)上看到一些說replace不起作用,我試了一下可以起作用的。暈一個(gè)先

mysql UPDATE alluser SET sex=REPLACE(sex, 0, 1) where id=2;

Query OK, 1 row affected (0.00 sec)

Rows matched: 1 Changed: 1 Warnings: 0

mysql select * from alluser;

+----+--------+-----+

| id | name | sex |

+----+--------+-----+

| 1 | 張映 | 0 |

| 1 | tank | 1 |

| 2 | tank2 | 1 |

+----+--------+-----+

3 rows in set (0.00 sec)

c,一個(gè) merge 表不能在整個(gè)表上維持 unique 約束。當(dāng)你執(zhí)行一個(gè) insert,數(shù)據(jù)進(jìn)入第一個(gè)或者最后一個(gè) myisam 表(取決于 insert_method 選項(xiàng)的值)。mysql 確保唯一鍵值在那個(gè) myisam 表里保持唯一,但不是跨集合里所有的表。

d,當(dāng)你創(chuàng)建一個(gè) merge 表之時(shí),沒有檢查去確保底層表的存在以及有相同的機(jī)構(gòu)。當(dāng) merge 表被使用之時(shí),mysql 檢查每個(gè)被映射的表的記錄長(zhǎng)度是否相等,但這并不十分可靠。如果你從不相似的 myisam 表創(chuàng)建一個(gè) merge 表,你非常有可能撞見奇怪的問題。

優(yōu)點(diǎn):擴(kuò)展性好,并且程序代碼改動(dòng)的不是很大

缺點(diǎn):這種方法的效果比第二種要差一點(diǎn)

三,總結(jié)一下

上面提到的三種方法,我實(shí)際做過二種,第一種和第二種。第三種沒有做過,所以說的細(xì)一點(diǎn)。哈哈。做什么事都有一個(gè)度,超過個(gè)度就過變得很差,不能一味的做數(shù)據(jù)庫服務(wù)器集群,硬件是要花錢買的,也不要一味的分表,分出來1000表,mysql的存儲(chǔ)歸根到底還以文件的形勢(shì)存在硬盤上面,一張表對(duì)應(yīng)三個(gè)文件,1000個(gè)分表就是對(duì)應(yīng)3000個(gè)文件,這樣檢索起來也會(huì)變的很慢。我的建議是

方法1和方法2結(jié)合的方式來進(jìn)行分表

方法1和方法3結(jié)合的方式來進(jìn)行分表

我的二個(gè)建議適合不同的情況,根據(jù)個(gè)人情況而定,我覺得會(huì)有很多人選擇方法1和方法3結(jié)合的方式

二,mysql分表和分區(qū)有什么區(qū)別呢

1,實(shí)現(xiàn)方式上

a),mysql的分表是真正的分表,一張表分成很多表后,每一個(gè)小表都是完正的一張表,都對(duì)應(yīng)三個(gè)文件,一個(gè).MYD數(shù)據(jù)文件,.MYI索引文件,.frm表結(jié)構(gòu)文件。

[root@BlackGhost test]# ls |grep user

alluser.MRG

alluser.frm

user1.MYD

user1.MYI

user1.frm

user2.MYD

user2.MYI

user2.frm

Php代碼

[root@BlackGhost test]# ls |grep user

alluser.MRG

alluser.frm

user1.MYD

user1.MYI

user1.frm

user2.MYD

user2.MYI

user2.frm

簡(jiǎn)單說明一下,上面的分表呢是利用了merge存儲(chǔ)引擎(分表的一種),alluser是總表,下面有二個(gè)分表,user1,user2。他們二個(gè)都是獨(dú)立的表,取數(shù)據(jù)的時(shí)候,我們可以通過總表來取。這里總表是沒有.MYD,.MYI這二個(gè)文件的,也就是說,總表他不是一張表,沒有數(shù)據(jù),數(shù)據(jù)都放在分表里面。我們來看看.MRG到底是什么東西

[root@BlackGhost test]# cat alluser.MRG |more

user1

user2

#INSERT_METHOD=LAST

Php代碼

[root@BlackGhost test]# cat alluser.MRG |more

user1

user2

#INSERT_METHOD=LAST

從上面我們可以看出,alluser.MRG里面就存了一些分表的關(guān)系,以及插入數(shù)據(jù)的方式。可以把總表理解成一個(gè)外殼,或者是聯(lián)接池。

b),分區(qū)不一樣,一張大表進(jìn)行分區(qū)后,他還是一張表,不會(huì)變成二張表,但是他存放數(shù)據(jù)的區(qū)塊變多了。

[root@BlackGhost test]# ls |grep aa

aa#P#p1.MYD

aa#P#p1.MYI

aa#P#p3.MYD

aa#P#p3.MYI

aa.frm

aa.par

Php代碼

[root@BlackGhost test]# ls |grep aa

aa#P#p1.MYD

aa#P#p1.MYI

aa#P#p3.MYD

aa#P#p3.MYI

aa.frm

aa.par

從上面我們可以看出,aa這張表,分為二個(gè)區(qū),p1和p3,本來是三個(gè)區(qū),被我刪了一個(gè)區(qū)。我們都知道一張表對(duì)應(yīng)三個(gè)文件.MYD,.MYI,.frm。分區(qū)呢根據(jù)一定的規(guī)則把數(shù)據(jù)文件和索引文件進(jìn)行了分割,還多出了一個(gè).par文件,打開.par文件后你可以看出他記錄了,這張表的分區(qū)信息,根分表中的.MRG有點(diǎn)像。分區(qū)后,還是一張,而不是多張表。

2,數(shù)據(jù)處理上

a),分表后,數(shù)據(jù)都是存放在分表里,總表只是一個(gè)外殼,存取數(shù)據(jù)發(fā)生在一個(gè)一個(gè)的分表里面??聪旅娴睦樱?/p>

select * from alluser where id=’12′表面上看,是對(duì)表alluser進(jìn)行操作的,其實(shí)不是的。是對(duì)alluser里面的分表進(jìn)行了操作。

b),分區(qū)呢,不存在分表的概念,分區(qū)只不過把存放數(shù)據(jù)的文件分成了許多小塊,分區(qū)后的表呢,還是一張表。數(shù)據(jù)處理還是由自己來完成。

3,提高性能上

a),分表后,單表的并發(fā)能力提高了,磁盤I/O性能也提高了。并發(fā)能力為什么提高了呢,因?yàn)椴閷ひ淮嗡ǖ臅r(shí)間變短了,如果出現(xiàn)高并發(fā)的話,總表可以根據(jù)不同的查詢,將并發(fā)壓力分到不同的小表里面。磁盤I/O性能怎么搞高了呢,本來一個(gè)非常大的.MYD文件現(xiàn)在也分?jǐn)偟礁鱾€(gè)小表的.MYD中去了。

b),mysql提出了分區(qū)的概念,我覺得就想突破磁盤I/O瓶頸,想提高磁盤的讀寫能力,來增加mysql性能。

在這一點(diǎn)上,分區(qū)和分表的測(cè)重點(diǎn)不同,分表重點(diǎn)是存取數(shù)據(jù)時(shí),如何提高mysql并發(fā)能力上;而分區(qū)呢,如何突破磁盤的讀寫能力,從而達(dá)到提高mysql性能的目的。

4),實(shí)現(xiàn)的難易度上

a),分表的方法有很多,用merge來分表,是最簡(jiǎn)單的一種方式。這種方式根分區(qū)難易度差不多,并且對(duì)程序代碼來說可以做到透明的。如果是用其他分表方式就比分區(qū)麻煩了。

b),分區(qū)實(shí)現(xiàn)是比較簡(jiǎn)單的,建立分區(qū)表,根建平常的表沒什么區(qū)別,并且對(duì)開代碼端來說是透明的。

三,mysql分表和分區(qū)有什么聯(lián)系呢

1,都能提高mysql的性高,在高并發(fā)狀態(tài)下都有一個(gè)良好的表面。

2,分表和分區(qū)不矛盾,可以相互配合的,對(duì)于那些大訪問量,并且表數(shù)據(jù)比較多的表,我們可以采取分表和分區(qū)結(jié)合的方式(如果merge這種分表方式,不能和分區(qū)配合的話,可以用其他的分表試),訪問量不大,但是表數(shù)據(jù)很多的表,我們可以采取分區(qū)的方式等。

MySQL分頁的sql語言怎么寫?

1、首先我們建立一個(gè)表表的數(shù)據(jù),這個(gè)表里有25條數(shù)據(jù),id從1到25。(下圖是部分截圖)

2、要分頁數(shù)據(jù),首先我們假設(shè)一頁有10條數(shù)據(jù),我們可以用mysql的limit關(guān)鍵字來限定返回多少條數(shù)據(jù)。并且用orderby來排序數(shù)據(jù),這里用id來排序。所以第一頁的sql可以如圖這樣寫。

3、執(zhí)行后得到的數(shù)據(jù)如圖,就是id從1到10的前10條數(shù)據(jù),因?yàn)槲覀兪前磇d升序來排序的。

4、上面第一頁的sql是簡(jiǎn)化的寫法,完整的寫法如圖,得到的結(jié)果和上圖的一模一樣。代碼里limit0,10的意思是從第一條數(shù)據(jù)開始,取10條數(shù)據(jù)。(注意的是第一條數(shù)據(jù)是從0開始的)

5、那么第二頁的數(shù)據(jù),關(guān)鍵是要知道是從哪一條數(shù)據(jù)開始,可以用這個(gè)公式得到:(頁碼-1)?*每頁顯示多少條,即(2-1)*10=10,所以sql語句如圖,limit10,10。

6、執(zhí)行后,結(jié)果正確,得到id從11到20的10條數(shù)據(jù)。

7、同理第三頁數(shù)據(jù)的sql如圖,br/就是limit20,10。

8、查詢的結(jié)果如圖,因?yàn)檫@頁只剩下5條數(shù)據(jù)了,所以只顯示5條數(shù)據(jù)。如果你有更多頁的數(shù)據(jù),后面的數(shù)據(jù)只需要按上面的公式,得到從哪行開始,就可以寫對(duì)應(yīng)的sql語句了。

oracle和mysql的分頁查詢?cè)趺磳?/h2>

Mysql分頁采用limt關(guān)鍵字 select * from t_order limit 5,10; #返回第6-15行數(shù)據(jù) select * from t_order limit 5; #返回前5行 select * from t_order limit 0,5; #返回前5行 Mssql 2000分頁采用top關(guān)鍵字(20005以上版本也支持關(guān)鍵字rownum) Select top 10 * from t_order where id not in (select id from t_order where id5 ); //返回第6到15行數(shù)據(jù) 其中10表示取10記錄 5表示從第5條記錄開始取

Oracle分頁

①采用rownum關(guān)鍵字(三層嵌套) SELECT * FROM( SELECT A.*,ROWNUM num FROM (SELECT * FROM t_order)A WHERE ROWNUM=15) WHERE num=5;--返回第5-15行數(shù)據(jù) ②采用row_number解析函數(shù)進(jìn)行分頁(效率更高) SELECT xx.* FROM( SELECT t.*,row_number() over(ORDER BY o_id)AS num FROM t_order t )xx WHERE num BETWEEN 5 AND 15; --返回第5-15行數(shù)據(jù) 解析函數(shù)能用格式 函數(shù)() over(pertion by 字段 order by 字段); Pertion 按照某個(gè)字段分區(qū) Order 按照勒個(gè)字段排序 用分析函數(shù) 一萬條后翻最后一頁會(huì)很慢,使用ROWNUM 一萬條之后每翻一頁都會(huì)慢

希望對(duì)你有所幫助

MySQL Mycat 分布式架構(gòu)

參考:

圖中是兩組分片,紅色我們稱為shard1,藍(lán)色我們稱為shard2

51 52是服務(wù)器

兩個(gè)3307互為主從(雙主),3309是本地3307的從庫

說明:沒有明確說明是只在某一個(gè)節(jié)點(diǎn)上做的,就是兩個(gè)節(jié)點(diǎn)都做

兩臺(tái)虛擬機(jī) db01 db02

每臺(tái)創(chuàng)建四個(gè)mysql實(shí)例:3307 3308 3309 3310

mysql軟件我們之前已完成二進(jìn)制安裝,直接初始化即可

我們server-id規(guī)劃為:db01上是7/8/9/10,db02上是17/18/19/20

"箭頭指向誰是主庫"

10.0.0.51:3307 ----- 10.0.0.52:3307

10.0.0.51:3309 ------ 10.0.0.51:3307

10.0.0.52:3309 ------ 10.0.0.52:3307

兩個(gè)分片,每個(gè)分片四個(gè)mysql節(jié)點(diǎn)

shard1:

Master:10.0.0.51:3307

slave1:10.0.0.51:3309

Standby Master:10.0.0.52:3307

slave2:10.0.0.52:3309

shard2:

Master:10.0.0.52:3308

slave1:10.0.0.52:3310

Standby Master:10.0.0.51:3308

slave2:10.0.0.51:3310

shard1

10.0.0.51:3307 ----- 10.0.0.52:3307

db02

db01

db02

10.0.0.51:3309 ------ 10.0.0.51:3307

db01

10.0.0.52:3309 ------ 10.0.0.52:3307

db02

shard2

10.0.0.52:3308 ----- 10.0.0.51:3308

db01

db02

db01

10.0.0.52:3310 ----- 10.0.0.52:3308

db02

10.0.0.51:3310 ----- 10.0.0.51:3308

db01

這個(gè)復(fù)制用戶在誰上建都行

注:如果中間出現(xiàn)錯(cuò)誤,在每個(gè)節(jié)點(diǎn)進(jìn)行執(zhí)行以下命令

常見方案:

360 Atlas-Sharding 360

Alibaba cobar 阿里

Mycat 開源

TDDL 淘寶

Heisenberg 百度

Oceanus 58同城

Vitess 谷歌

OneProxy

DRDS 阿里云

我們裝的是openjdk,不是官方的那個(gè)

Mycat-server-xxxxx.linux.tar.gz

配置環(huán)境變量

我們mycat的命令也是在bin目錄下

啟動(dòng)

8066就是對(duì)外提供服務(wù)的端口,9066是管理端口

連接mycat:

默認(rèn)123456

db01:

我們一般先把原schema.xml備份,然后自己新寫一個(gè):

xml和html看起來差不多,xml是從下往上調(diào)用的

前三行我們不用看,直接從第四行schema開始看起:

定義了schema,然后以/schema結(jié)尾

為什么要用邏輯庫?

業(yè)務(wù)透明化

此配置文件就是實(shí)現(xiàn)讀寫分離的配置

重啟mycat

讀寫分離測(cè)試

總結(jié):

以上案例實(shí)現(xiàn)了1主1從的讀寫分離功能,寫操作落到主庫,讀操作落到從庫.如果主庫宕機(jī),從庫不能在繼續(xù)提供服務(wù)了。

我們推薦這種架構(gòu)

一寫三讀,

不設(shè)置雙寫的原因是:性能沒提升多少,反而引起主鍵沖突的情況

配置文件:

之后重啟:mycat restart

真正的 writehost:負(fù)責(zé)寫操作的writehost

standby writeHost :和readhost一樣,只提供讀服務(wù)

我們此處寫了兩個(gè)writehost,默認(rèn)使用第一個(gè)

當(dāng)寫節(jié)點(diǎn)宕機(jī)后,后面跟的readhost也不提供服務(wù),這時(shí)候standby的writehost就提供寫服務(wù),

后面跟的readhost提供讀服務(wù)

測(cè)試:

讀寫分離測(cè)試

對(duì)db01 3307節(jié)點(diǎn)進(jìn)行關(guān)閉和啟動(dòng),測(cè)試讀寫操作

結(jié)果應(yīng)為另一臺(tái)(52)的3307(17)是寫,3309(19)是讀

一旦7號(hào)節(jié)點(diǎn)恢復(fù),此時(shí)因?yàn)?落后了,寫節(jié)點(diǎn)仍是17

balance屬性

負(fù)載均衡類型,目前的取值有3種:

writeType屬性

負(fù)載均衡類型,目前的取值有2種:

switchType屬性

-1 表示不自動(dòng)切換

1 默認(rèn)值,自動(dòng)切換

2 基于MySQL主從同步的狀態(tài)決定是否切換 ,心跳語句為 show slave status

datahost其他配置

dataHost name="localhost1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1"

maxCon="1000":最大的并發(fā)連接數(shù)

minCon="10" :mycat在啟動(dòng)之后,會(huì)在后端節(jié)點(diǎn)上自動(dòng)開啟的連接線程,長(zhǎng)連接,好處是連接速度快,弊端是占內(nèi)存

tempReadHostAvailable="1"

這個(gè)一主一從時(shí)(1個(gè)writehost,1個(gè)readhost時(shí)),可以開啟這個(gè)參數(shù),如果2個(gè)writehost,2個(gè)readhost時(shí)

heartbeatselect user()/heartbeat 監(jiān)測(cè)心跳

其他參數(shù)sqlMaxLimit自動(dòng)分頁,必須在啟用分表的情況下才生效

創(chuàng)建測(cè)試庫和表:

我們重啟mycat后連接到8066

發(fā)現(xiàn)跟一個(gè)庫一樣,實(shí)際上已經(jīng)分到不同的物理硬件上了

分片:對(duì)一個(gè)"bigtable",比如說t3表

熱點(diǎn)數(shù)據(jù)表 核心表

(1)行數(shù)非常多,800w下坡

(2)訪問非常頻繁

分片的目的:

(1)將大數(shù)據(jù)量進(jìn)行分布存儲(chǔ)

(2)提供均衡的訪問路由

分片策略:

范圍 range 800w 1-400w 400w01-800w 不適用于業(yè)務(wù)訪問不均勻的情況

取模 mod (取余數(shù)) 和節(jié)點(diǎn)的數(shù)量進(jìn)行取模

枚舉 按枚舉的種類分,如移動(dòng)項(xiàng)目按省份分

哈希 hash

時(shí)間 流水

優(yōu)化關(guān)聯(lián)查詢(否則join的表在不同分片上,效率會(huì)比單庫還要低)

全局表

ER分片

案例:移動(dòng)統(tǒng)一:先拆出邊緣業(yè)務(wù),再按地域分片,但對(duì)應(yīng)用來說是統(tǒng)一的

vim rule.xml

tableRule name="auto-sharding-long"

rule

columnsid/columns

algorithmrang-long/algorithm

/rule

function name="rang-long"

class="io.mycat.route.function.AutoPartitionByLong"

property name="mapFile"autopartition-long.txt/property

/function

===================================

vim autopartition-long.txt

0-10=0

11-20=1

創(chuàng)建測(cè)試表:

mysql -S /data/3307/mysql.sock -e "use taobao;create table t3 (id int not null primary key auto_increment,name varchar(20) not null);"

mysql -S /data/3308/mysql.sock -e "use taobao;create table t3 (id int not null primary key auto_increment,name varchar(20) not null);"

測(cè)試:

重啟mycat

mycat restart

mysql -uroot -p123456 -h 127.0.0.1 -P 8066

insert into t3(id,name) values(1,'a');

insert into t3(id,name) values(2,'b');

insert into t3(id,name) values(3,'c');

insert into t3(id,name) values(4,'d');

insert into t3(id,name) values(11,'aa');

insert into t3(id,name) values(12,'bb');

insert into t3(id,name) values(13,'cc');

insert into t3(id,name) values(14,'dd');

取余分片方式:分片鍵(一個(gè)列)與節(jié)點(diǎn)數(shù)量進(jìn)行取余,得到余數(shù),將數(shù)據(jù)寫入對(duì)應(yīng)節(jié)點(diǎn)

vim schema.xml

table name="t4" dataNode="sh1,sh2" rule="mod-long" /

vim rule.xml

property name="count"2/property

準(zhǔn)備測(cè)試環(huán)境

創(chuàng)建測(cè)試表:

mysql -S /data/3307/mysql.sock -e "use taobao;create table t4 (id int not null primary key auto_increment,name varchar(20) not null);"

mysql -S /data/3308/mysql.sock -e "use taobao;create table t4 (id int not null primary key auto_increment,name varchar(20) not null);"

重啟mycat

mycat restart

測(cè)試:

mysql -uroot -p123456 -h10.0.0.52 -P8066

use TESTDB

insert into t4(id,name) values(1,'a');

insert into t4(id,name) values(2,'b');

insert into t4(id,name) values(3,'c');

insert into t4(id,name) values(4,'d');

分別登錄后端節(jié)點(diǎn)查詢數(shù)據(jù)

mysql -S /data/3307/mysql.sock

use taobao

select * from t4;

mysql -S /data/3308/mysql.sock

use taobao

select * from t4;

t5 表

id name telnum

1 bj 1212

2 sh 22222

3 bj 3333

4 sh 44444

5 bj 5555

sharding-by-intfile

vim schema.xml

table name="t5" dataNode="sh1,sh2" rule="sharding-by-intfile" /

vim rule.xml

tableRule name="sharding-by-intfile"

rule columnsname/columns

algorithmhash-int/algorithm

/rule

/tableRule

function name="hash-int" class="org.opencloudb.route.function.PartitionByFileMap"

property name="mapFile"partition-hash-int.txt/property

property name="type"1/property

property name="defaultNode"0/property

/function

partition-hash-int.txt 配置:

bj=0

sh=1

DEFAULT_NODE=1

columns 標(biāo)識(shí)將要分片的表字段,algorithm 分片函數(shù), 其中分片函數(shù)配置中,mapFile標(biāo)識(shí)配置文件名稱

準(zhǔn)備測(cè)試環(huán)境

mysql -S /data/3307/mysql.sock -e "use taobao;create table t5 (id int not null primary key auto_increment,name varchar(20) not null);"

mysql -S /data/3308/mysql.sock -e "use taobao;create table t5 (id int not null primary key auto_increment,name varchar(20) not null);"

重啟mycat

mycat restart

mysql -uroot -p123456 -h10.0.0.51 -P8066

use TESTDB

insert into t5(id,name) values(1,'bj');

insert into t5(id,name) values(2,'sh');

insert into t5(id,name) values(3,'bj');

insert into t5(id,name) values(4,'sh');

insert into t5(id,name) values(5,'tj');

a b c d

join

t

select t1.name ,t.x from t1

join t

select t2.name ,t.x from t2

join t

select t3.name ,t.x from t3

join t

使用場(chǎng)景:

如果你的業(yè)務(wù)中有些數(shù)據(jù)類似于數(shù)據(jù)字典,比如配置文件的配置,

常用業(yè)務(wù)的配置或者數(shù)據(jù)量不大很少變動(dòng)的表,這些表往往不是特別大,

而且大部分的業(yè)務(wù)場(chǎng)景都會(huì)用到,那么這種表適合于Mycat全局表,無須對(duì)數(shù)據(jù)進(jìn)行切分,

要在所有的分片上保存一份數(shù)據(jù)即可,Mycat 在Join操作中,業(yè)務(wù)表與全局表進(jìn)行Join聚合會(huì)優(yōu)先選擇相同分片內(nèi)的全局表join,

避免跨庫Join,在進(jìn)行數(shù)據(jù)插入操作時(shí),mycat將把數(shù)據(jù)分發(fā)到全局表對(duì)應(yīng)的所有分片執(zhí)行,在進(jìn)行數(shù)據(jù)讀取時(shí)候?qū)?huì)隨機(jī)獲取一個(gè)節(jié)點(diǎn)讀取數(shù)據(jù)。

vim schema.xml

table name="t_area" primaryKey="id" type="global" dataNode="sh1,sh2" /

后端數(shù)據(jù)準(zhǔn)備

mysql -S /data/3307/mysql.sock

use taobao

create table t_area (id int not null primary key auto_increment,name varchar(20) not null);

mysql -S /data/3308/mysql.sock

use taobao

create table t_area (id int not null primary key auto_increment,name varchar(20) not null);

重啟mycat

mycat restart

測(cè)試:

mysql -uroot -p123456 -h10.0.0.52 -P8066

use TESTDB

insert into t_area(id,name) values(1,'a');

insert into t_area(id,name) values(2,'b');

insert into t_area(id,name) values(3,'c');

insert into t_area(id,name) values(4,'d');

A

join

B

為了防止跨分片join,可以使用E-R模式

A join B

on a.xx=b.yy

join C

on A.id=C.id

table name="A" dataNode="sh1,sh2" rule="mod-long"

childTable name="B" joinKey="yy" parentKey="xx" /

/table


新聞標(biāo)題:mysql的分片怎么寫 2021年9月18日國難日結(jié)婚
文章起源:http://weahome.cn/article/ddejcid.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部