国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

數(shù)據(jù)庫(kù)系列文章 之 MySQL分表的三種方法

這篇具有很好參考價(jià)值的文章主要介紹了數(shù)據(jù)庫(kù)系列文章 之 MySQL分表的三種方法。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

先說(shuō)一下為什么要分表
當(dāng)一張的數(shù)據(jù)達(dá)到幾百萬(wàn)時(shí),你查詢一次所花的時(shí)間會(huì)變多,如果有聯(lián)合查詢的話,我想有可能會(huì)死在那兒了。分表的目的就在于此,減小數(shù)據(jù)庫(kù)的負(fù)擔(dān),縮短查詢時(shí)間。
根據(jù)個(gè)人經(jīng)驗(yàn),mysql執(zhí)行一個(gè)sql的過(guò)程如下:
1,接收到sql;2,把sql放到排隊(duì)隊(duì)列中 ;3,執(zhí)行sql;4,返回執(zhí)行結(jié)果。在這個(gè)執(zhí)行過(guò)程中最花時(shí)間在什么地方呢?第一,是排隊(duì)等待的時(shí)間,第二,sql的執(zhí)行時(shí)間。其實(shí)這二個(gè)是一回事,等待的同時(shí),肯定有sql在執(zhí)行。所以我們要縮短sql的執(zhí)行時(shí)間。

mysql中有一種機(jī)制是表鎖定和行鎖定,為什么要出現(xiàn)這種機(jī)制,是為了保證數(shù)據(jù)的完整性,我舉個(gè)例子來(lái)說(shuō)吧,如果有二個(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>

分表方法一:

做mysql集群,例如:利用mysql cluster ,mysql proxy,mysql replication,drdb等等
有人會(huì)問(wèn)mysql集群,根分表有什么關(guān)系嗎?雖然它不是實(shí)際意義上的分表,但是它啟到了分表的作用,做集群的意義是什么呢?為一個(gè)數(shù)據(jù)庫(kù)減輕負(fù)擔(dān),說(shuō)白了就是減少sql排隊(duì)隊(duì)列中的sql的數(shù)量,舉個(gè)例子:有10個(gè)sql請(qǐng)求,如果放在一個(gè)數(shù)據(jù)庫(kù)服務(wù)器的排隊(duì)隊(duì)列中,他要等很長(zhǎng)時(shí)間,如果把這10個(gè)sql請(qǐng)求,分配到5個(gè)數(shù)據(jù)庫(kù)服務(wù)器的排隊(duì)隊(duì)列中,一個(gè)數(shù)據(jù)庫(kù)服務(wù)器的隊(duì)列中只有2個(gè),這樣等待時(shí)間是不是大大的縮短了呢?這已經(jīng)很明顯了。所以我把它列到了分表的范圍以內(nèi),我做過(guò)一些mysql的集群:
linux mysql proxy 的安裝,配置,以及讀寫(xiě)分離
mysql replication 互為主從的安裝及配置,以及數(shù)據(jù)同步
優(yōu)點(diǎn):擴(kuò)展性好,沒(méi)有多個(gè)分表后的復(fù)雜操作(php代碼)
缺點(diǎn):?jiǎn)蝹€(gè)表的數(shù)據(jù)量還是沒(méi)有變,一次操作所花的時(shí)間還是那么多,硬件開(kāi)銷大。

分表方法二:

預(yù)先估計(jì)會(huì)出現(xiàn)大數(shù)據(jù)量并且訪問(wèn)頻繁的表,將其分為若干個(gè)表
這種預(yù)估大差不差的,論壇里面發(fā)表帖子的表,時(shí)間長(zhǎng)了這張表肯定很大,幾十萬(wàn),幾百萬(wàn)都有可能。 聊天室里面信息表,幾十個(gè)人在一起一聊一個(gè)晚上,時(shí)間長(zhǎng)了,這張表的數(shù)據(jù)肯定很大。像這樣的情況很多。所以這種能預(yù)估出來(lái)的大數(shù)據(jù)量表,我們就事先分出個(gè)N個(gè)表,這個(gè)N是多少,根據(jù)實(shí)際情況而定。以聊天信息表為例:
我事先建100個(gè)這樣的表,message_00,message_01,message_02..........message_98,message_99.然后根據(jù)用戶的ID來(lái)判斷這個(gè)用戶的聊天信息放到哪張表里面,你可以用hash的方式來(lái)獲得,可以用求余的方式來(lái)獲得

//hash方式

function?get_hash_table($table,$userid) {?

?$str?= crc32($userid);?

?if($str<0){?

?$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

//取模方式

function?hash_table($table_name,?$user_id,?$total)

{

????return?$table_name?.?'_'?. (($user_id?%?$total) + 1);

}

??

echo?hash_table("artice", 1234, 5);?//artice_5

echo?hash_table("artice", 3243, 5);?//artice_4

  

說(shuō)明一下,上面的這個(gè)方法,告訴我們user18991這個(gè)用戶的消息都記錄在message_10這張表里,user34523這個(gè)用戶的消息都記錄在message_13這張表里,讀取的時(shí)候,只要從各自的表中讀取就行了。
優(yōu)點(diǎn):避免一張表出現(xiàn)幾百萬(wà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ò)展性很差。

分表方法三:

利用merge存儲(chǔ)引擎來(lái)實(shí)現(xiàn)分表
我覺(jué)得這種方法比較適合,那些沒(méi)有事先考慮,而已經(jīng)出現(xiàn)了得,數(shù)據(jù)查詢慢的情況。這個(gè)時(shí)候如果要把已有的大數(shù)據(jù)量表分開(kāi)比較痛苦,最痛苦的事就是改代碼,因?yàn)槌绦蚶锩娴膕ql語(yǔ)句已經(jīng)寫(xiě)好了,現(xiàn)在一張表要分成幾十張表,甚至上百?gòu)埍恚@樣sql語(yǔ)句是不是要重寫(xiě)呢?舉個(gè)例子,我很喜歡舉子
mysql>show engines;的時(shí)候你會(huì)發(fā)現(xiàn)mrg_myisam其實(shí)就是merge。

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)

從上面的操作中,我不知道你有沒(méi)有發(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è)問(wèn)題,代碼中的sql語(yǔ)句怎么辦,以前是一張表,現(xiàn)在變成二張表了,代碼改動(dòng)很大,這樣給程序員帶來(lái)了很大的工作量,有沒(méi)有好的辦法解決這一點(diǎn)呢?辦法是把以前的user表備份一下,然后刪除掉,上面的操作中我建立了一個(gè)alluser表,只把這個(gè)alluser表的表名改成user就行了。但是,不是所有的mysql操作都能用的
a,如果你使用 alter table 來(lái)把 merge 表變?yōu)槠渌眍愋?,到底層表的映射就被丟失了。取而代之的,來(lái)自底層 myisam 表的行被復(fù)制到已更換的表中,該表隨后被指定新類型。
b,網(wǎng)上看到一些說(shuō)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í),沒(méi)有檢查去確保底層表的存在以及有相同的機(jī)構(gòu)。當(dāng) merge 表被使用之時(shí),mysql 檢查每個(gè)被映射的表的記錄長(zhǎng)度是否相等,但這并不十分可靠。如果你從不相似的 myisam 表創(chuàng)建一個(gè) merge 表,你非常有可能撞見(jiàn)奇怪的問(wèn)題。
好困睡覺(jué)了,c和d在網(wǎng)上看到的,沒(méi)有測(cè)試,大家試一下吧。
優(yōu)點(diǎn):擴(kuò)展性好,并且程序代碼改動(dòng)的不是很大
缺點(diǎn):這種方法的效果比第二種要差一點(diǎn)

總結(jié)一下
上面提到的三種方法,我實(shí)際做過(guò)二種,第一種和第二種。第三種沒(méi)有做過(guò),所以說(shuō)的細(xì)一點(diǎn)。哈哈。做什么事都有一個(gè)度,超過(guò)個(gè)度就過(guò)變得很差,不能一味的做數(shù)據(jù)庫(kù)服務(wù)器集群,硬件是要花錢(qián)買(mǎi)的,也不要一味的分表,分出來(lái)1000表,mysql的存儲(chǔ)歸根到底還以文件的形勢(shì)存在硬盤(pán)上面,一張表對(duì)應(yīng)三個(gè)文件,1000個(gè)分表就是對(duì)應(yīng)3000個(gè)文件,這樣檢索起來(lái)也會(huì)變的很慢。我的建議是
方法1和方法2結(jié)合的方式來(lái)進(jìn)行分表
方法1和方法3結(jié)合的方式來(lái)進(jìn)行分表
我的二個(gè)建議適合不同的情況,根據(jù)個(gè)人情況而定,我覺(jué)得會(huì)有很多人選擇方法1和方法3結(jié)合的方式文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-570230.html

到了這里,關(guān)于數(shù)據(jù)庫(kù)系列文章 之 MySQL分表的三種方法的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • sql文件導(dǎo)入數(shù)據(jù)庫(kù)的三種方式

    sql文件導(dǎo)入數(shù)據(jù)庫(kù)的三種方式

    方式一:在數(shù)據(jù)庫(kù)的表中直接右鍵運(yùn)行sql文件 ? ?方式二:終端窗口 cmd,管理員身份運(yùn)行 C:WINDOWSsystem32mysql -uroot -p 輸入密碼 use 數(shù)據(jù)庫(kù)名; mysql use reggie; source sql文件路徑(不能含有中文) 方式三:在數(shù)據(jù)庫(kù)或終端輸入sql指令 新建查詢--輸入sql語(yǔ)句--運(yùn)行

    2024年02月03日
    瀏覽(27)
  • 掌握MySQL分庫(kù)分表(一)數(shù)據(jù)庫(kù)性能優(yōu)化思路、分庫(kù)分表優(yōu)缺點(diǎn)

    不能?上來(lái)就說(shuō)分庫(kù)分表! 根據(jù)實(shí)際情況分析,兩個(gè)角度思考:不分庫(kù)分表、分庫(kù)分表 軟優(yōu)化 數(shù)據(jù)庫(kù)參數(shù)調(diào)優(yōu) 分析慢查詢SQL語(yǔ)句,分析執(zhí)行計(jì)劃,進(jìn)行sql改寫(xiě)和程序改寫(xiě) 優(yōu)化數(shù)據(jù)庫(kù)索引結(jié)構(gòu) 優(yōu)化數(shù)據(jù)表結(jié)構(gòu)優(yōu)化 引入NOSQL和程序架構(gòu)調(diào)整 硬優(yōu)化 提升系統(tǒng)硬件(更快的IO、更

    2023年04月19日
    瀏覽(36)
  • PostgreSQL數(shù)據(jù)庫(kù)命令行執(zhí)行SQL腳本的三種方式

    PostgreSQL數(shù)據(jù)庫(kù)命令行執(zhí)行SQL腳本的三種方式

    生成環(huán)境中,出于安全性等原因,往往不提供數(shù)據(jù)庫(kù)連接工具,所以對(duì)數(shù)據(jù)庫(kù)的更新和升級(jí)就得通過(guò)命令行來(lái)實(shí)現(xiàn)。本文總結(jié)了三種命令行執(zhí)行sql腳本的方式。 命令格式: psql [option…] [dbname] [username] 常用參數(shù)介紹: -h:指定IP地址或主機(jī)名。 -p:指定端口,默認(rèn)為5432。 -U:

    2024年02月11日
    瀏覽(26)
  • 編寫(xiě)shell腳本,利用mysqldump實(shí)現(xiàn)MySQL數(shù)據(jù)庫(kù)分庫(kù)分表備份

    編寫(xiě)shell腳本,利用mysqldump實(shí)現(xiàn)MySQL數(shù)據(jù)庫(kù)分庫(kù)分表備份

    ?查看數(shù)據(jù)和數(shù)據(jù)表 刪除頭部Database和數(shù)據(jù)庫(kù)自帶的表 ?編寫(xiě)腳本 檢查腳本運(yùn)行備份數(shù)據(jù)庫(kù) 分表分庫(kù)備份成功 還原檢測(cè) 刪除數(shù)據(jù)庫(kù)并查看庫(kù) 開(kāi)始還原 使用備份的庫(kù)進(jìn)行還原,由于是壓縮文件,使用壓縮還原 查看數(shù)據(jù)庫(kù) ?

    2024年02月05日
    瀏覽(26)
  • 還原Sql Server數(shù)據(jù)庫(kù)BAK備份文件的三種方式及常見(jiàn)錯(cuò)誤

    還原Sql Server數(shù)據(jù)庫(kù)BAK備份文件的三種方式及常見(jiàn)錯(cuò)誤

    這是演示的是Sql Server 2008R2版本,不同版本可能有細(xì)微差別 右鍵點(diǎn)擊數(shù)據(jù)庫(kù)→還原數(shù)據(jù)庫(kù) ? ?在還原的源中選擇源設(shè)備→點(diǎn)擊選擇框 ?在指定備份中點(diǎn)擊添加→選擇具體文件→確定→確定 ?勾選用于還原的備份集→這時(shí)目標(biāo)數(shù)據(jù)庫(kù)中會(huì)自動(dòng)生成目標(biāo)數(shù)據(jù)庫(kù)名,在此選擇即可→

    2023年04月08日
    瀏覽(94)
  • 【大數(shù)據(jù)系列之MySQL】(七):MySQL查看版本號(hào)的三種方式

    【大數(shù)據(jù)系列之MySQL】(七):MySQL查看版本號(hào)的三種方式

    第一種方式就是通過(guò)命令行,輸入指令: 方式二和方式一是同樣的道理,只不過(guò)可以將命令進(jìn)行簡(jiǎn)寫(xiě): 第三種方式是通過(guò)登錄MySQL的服務(wù)端,通過(guò)指令:

    2024年04月15日
    瀏覽(19)
  • MongoDB數(shù)據(jù)庫(kù)從入門(mén)到精通系列文章之:MongoDB數(shù)據(jù)庫(kù)百篇技術(shù)文章匯總

    MongoDB數(shù)據(jù)庫(kù)系列文章持續(xù)更新中: 更多數(shù)據(jù)庫(kù)內(nèi)容請(qǐng)閱讀博主數(shù)據(jù)庫(kù)專欄,數(shù)據(jù)庫(kù)專欄涵蓋了Mysql、SQLServer、PostgreSQL、MongoDB、Oracle、Cassandra等數(shù)據(jù)庫(kù) 數(shù)據(jù)庫(kù)專欄 文章名稱 文章鏈接 數(shù)據(jù)庫(kù)安裝部署系列之:部署Mongodb5.0.6高可用集群詳細(xì)步驟 數(shù)據(jù)庫(kù)安裝部署系列之:部署M

    2024年02月11日
    瀏覽(54)
  • 3、數(shù)據(jù)庫(kù):Oracle部署  - 系統(tǒng)部署系列文章

    3、數(shù)據(jù)庫(kù):Oracle部署 - 系統(tǒng)部署系列文章

    ?????? Oracle數(shù)據(jù)庫(kù)的安裝,以前寫(xiě)過(guò)一篇,這次將新版的安裝再記錄一次,讓讀者能夠有所了解,筆者也能夠記錄下最新版的安裝過(guò)程。 一、 數(shù)據(jù)庫(kù)下載; Oracle最新版目前在官網(wǎng)是19c,從下面這個(gè)鏈接進(jìn)去下載便可。 ?????? https://www.oracle.com/cn/database/technologies/oracle

    2024年02月07日
    瀏覽(22)
  • 數(shù)據(jù)庫(kù)中的字段名與實(shí)體類中的屬性名不能一一對(duì)應(yīng)時(shí)的三種處理方式

    數(shù)據(jù)庫(kù)中的字段名與實(shí)體類中的屬性名不能一一對(duì)應(yīng)時(shí)的三種處理方式

    當(dāng)查詢結(jié)果的列名和java對(duì)象的屬性名對(duì)應(yīng)不上時(shí)需要采用下列方式進(jìn)行處理: ????????第一種方式:在查詢語(yǔ)句中使用\\\"as\\\" 給列起別名 ????????第二種方式:使用resultMap結(jié)果映射 ????????第三種方式:開(kāi)啟駝峰命名自動(dòng)映射(配置settings) 實(shí)體類Car: packa

    2024年02月09日
    瀏覽(19)
  • MySQL數(shù)據(jù)庫(kù)——MySQL數(shù)據(jù)表添加字段(三種方式)

    MySQL 數(shù)據(jù)表是由行和列構(gòu)成的,通常把表的“列”稱為字段(Field),把表的“行”稱為記錄(Record)。隨著業(yè)務(wù)的變化,可能需要在已有的表中添加新的字段。 MySQL 允許在開(kāi)頭、中間和結(jié)尾處添加字段。 一個(gè)完整的字段包括字段名、數(shù)據(jù)類型和約束條件。MySQL 添加字段的語(yǔ)

    2024年02月08日
    瀏覽(101)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包