概述今天主要看下innodb是怎么去設(shè)計(jì)主鍵索引的,這里引用了一個(gè)淘寶MySQL數(shù)據(jù)庫(kù)經(jīng)典案例。 innodb 主鍵索引在Innodb中,聚簇索引默認(rèn)就是主鍵索引。如果沒有主鍵,則按照下列規(guī)則來建聚簇索引: 沒有主鍵時(shí),會(huì)用一個(gè)非空并且唯一的索引列做為主鍵,成為此表的聚簇索引; 如果沒有這樣的索引,InnoDB會(huì)隱式定義一個(gè)主鍵來作為聚簇索引。 由于主鍵使用了聚簇索引,如果主鍵是自增id,那么對(duì)應(yīng)的數(shù)據(jù)也會(huì)相鄰地存放在磁盤上,寫入性能較高。如果是uuid等字符串形式,頻繁的插入會(huì)使innodb頻繁地移動(dòng) 磁盤塊,寫入性能就比較低了。
InnoDB是clustered-index table,因此對(duì)于InnoDB而言,主鍵具有特殊意義??梢酝ㄟ^主鍵直接定位到對(duì)應(yīng)的某一數(shù)據(jù)行記錄的物理位置,主鍵索引指向?qū)?yīng)行記錄,其他索引則都指向主鍵索引;因此,可以這么說,InnoDB其實(shí)就是一個(gè) B+樹索引,這棵B+樹的索引就是主鍵,它的值則是對(duì)應(yīng)的行記錄。 在InnoDB數(shù)據(jù)表設(shè)計(jì)中,我們需要注意幾點(diǎn):
再看一個(gè)淘寶MySQL經(jīng)典案例1、創(chuàng)建表大多數(shù)互聯(lián)網(wǎng)業(yè)務(wù)(用戶,消息)都可以用A表或者B表滿足需求,那么兩個(gè)表有什么區(qū)別呢? --創(chuàng)建表ACREATE TABLE `A` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`message_id` int(11) NOT NULL,`user_id` int(11) NOT NULL,`msg` varchar(1024) DEFAULT NULL,`gmt_create` datetime NOT NULL,PRIMARY KEY (`id`),KEY `user_id` (`user_id`,`message_id`),KEY `idx_gmt_create` (`gmt_create`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;--創(chuàng)建表BCREATE TABLE `B` (`user_id` int(11) NOT NULL,`message_id` int(11) NOT NULL,`msg` varchar(1024) DEFAULT NULL,`gmt_create` datetime NOT NULL,PRIMARY KEY (`user_id`,`message_id`),KEY `idx_gmt_create` (`gmt_create`)) ENGINE=InnoDB DEFAULT CHARSET=utf8; 2、對(duì)比分析AB表對(duì)比分析如下: 總結(jié)因?yàn)橹麈I是clustered index,采用自增id可以減少insert的時(shí)間。自增最大的問題就是分表分庫(kù)。 數(shù)據(jù)整合。 如果增加序列分發(fā)器 帶來的消耗也很高。 數(shù)據(jù)存儲(chǔ)碎片也難以消除。 主鍵設(shè)計(jì)是個(gè)折中的取舍。 |
|