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