innoDB建表tips
近期参与一个项目的建设中,第一次打开数据库看到建表项目的时候,表项内容引发了我的思考,顺便也复习了一波mysql基础
CREATE TABLE `XXXXInfoTab` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`fileHash` varchar(255) NOT NULL,
`peerId` varchar(255) NOT NULL,
`...` varchar(32) DEFAULT NULL,
`...` tinyint(4) DEFAULT '0',
`...` tinyint(4) DEFAULT '0',
.....
PRIMARY KEY (`id`),
UNIQUE KEY `unique_hash_id` (`fileHash`,`peerId`)
) ENGINE=InnoDB AUTO_INCREMENT=169 DEFAULT CHARSET=utf8mb4;
由于这个项目还没正式推出去,数据都是自己人测试出来的,故而自增的id并没有多大,燃鹅真正上线后根据这个表所设计的功能来看这个表里面的数据将会变得比较多,而且增删改查的动作比较多,由于自己经验比较局限平时开发也不怎么用mysql而且记性也不是很好所以先看看mysql有关的文章好了…
我们知道mysql要想查询速度增快我们需要做的就是建立好索引,而在innoDB建立索引又有一些要注意的事项:
- InnoDB单列索引长度不能超过767bytes
- 联合索引还有一个限制是长度不能超过3072
上面建表的语句可以看到主键id为单列索引,考虑到表会变很多数据,所以bigint(20)是没什么问题的;由于fileHash这个字段占用255*3,因此这个索引的大小为255 *3=765,因此这个索引的长度为765 *2=1530 。
主键不能超过767是因为主键是聚集索引,也是其他二级索引的基础,所以每个主键要在一个数据页存储,不能分布在其他的溢出页,不能像其他大字段一样溢出数据页,所以主键不能超过767位(5.5版本之后的my.ini文件中有个参数可以调整这个限制:innodb_large_prefix)
联合索引不能超过3072的原因是因为InnoDB一个page的默认大小是16k。由于是B+ tree组织,要求叶子节点上一个page至少要包含两条记录,否则就退化链表了所以一个记录最多不能超过8k。又由于InnoDB的聚簇索引结构,一个二级索引要包含主键索引,因此每个单个索引不能超过4k,由于需要预留和辅助空间,扣掉后不能超过3500,取个“整数”就是(1024*3)。
又看了一下fileHash和peerId,一个索引既然是独立于原数据要另外占空间的一个数据结构,而且长索引不如短索引在树结构中插入并排序,故而觉得应该把这两个索引的长度变小点儿。
`fileHash` varchar(68) NOT NULL,
`peerId` varchar(10) NOT NULL,