表结构设计的核心思想是什么?
- 表及表字段只增不减,即不删除表,不删除字段,只做增加。
- 使用
innodb
存储引擎,支持事务,MVCC,行级锁,更好的恢复性,更高效的IO,更先进的缓存,更先进的写策略。高并发下性能更好,对多核,大内存,SSD等硬件支持更好。 - 自增主键,推荐用独立于业务的
AUTO_INCREMENT
列或全局ID生成器做代理主键。 - 拆开宽表,便于运维,加快变更速度,提高查询性能,节省IO和内存。
- 控制单表数据量,纯INT不超过1000W,含VARCHAR不超过500w。建议单库不超过300-400个表。
- 控制列数据,越短越好,单表不超50个纯INT字段,VARCHAR(10)不超20个字段,单表字段数上限控制在20-50个。
- 表和字段加注释。
- 使用推荐的字段类型:
- 时间
timestamp
- 日期
date
- IP
int unsigned
INET_ATON('127.0.0.1')
INET_NTOA(ip)
- 小数
decimal
- 尽量不用
text/blob/char
,用varchar
- 字段只有
true or false
,用tinyint
- 非负数值,用
unsigned
- 默认值不能用
null
,数字类型用default 0
,字符类型用defalut ''
- 时间
- 不在数据库里存图片
- 禁用外键
建索引时要考虑哪些因素?
有个大表为了一个查询(一天就查2次),领导要你建索引(索引空间大小有500G),你怎么考虑,是建还是不建?
建索引常用的规则如下:
- 表的主键、外键必须有索引;
- 数据量超过300w的表应该有索引;
- 经常与其他表进行连接的表,在连接字段上应该建立索引;
- 经常出现在Where子句中的字段,特别是大表的字段,应该建立索引;
- 索引应该建在选择性高的字段上;
- 索引应该建在小字段上,对于大的文本字段甚至超长字段,不要建索引;
- 复合索引的建立需要进行仔细分析,尽量考虑用单字段索引代替
- 正确选择复合索引中的主列字段,一般是选择性较好的字段;
- 复合索引的几个字段是否经常同时以AND方式出现在Where子句中?单字段查询是否极少甚至没有?如果是,则可以建立复合索引;否则考虑单字段索引;
- 如果复合索引中包含的字段经常单独出现在Where子句中,则分解为多个单字段索引;
- 如果复合索引所包含的字段超过3个,那么仔细考虑其必要性,考虑减少复合的字段;
- 如果既有单字段索引,又有这几个字段上的复合索引,一般可以删除复合索引
- 频繁进行数据操作的表,不要建立太多的索引;
- 删除无用的索引,避免对执行计划造成负面影响
若有一个大表,建索引空间有500G,且一天就查2次,那我是不建议建索引的。
根据索引空间大小500G,基本可以判断表的记录应该在亿条数据级以上,且应该是一个类似于日志记录性质的表,且日志增涨应该较快。
这么大的表建索引时,首先会给数据库造成较大的影响,并且建索引后会影响表的写入性能。 在一天就查询2次这种业务需求下,建索引的代价是相对较大的。
执行计划中有 filesort 就会进行磁盘文件排序吗(详细说明)?
filesort是在使用explain命令查看一条SQL的执行计划的时候可能会看到在 “Extra” 一列显示的信息。
filesort表示MySQL需要进行实际的排序操作,而不能通过索引获得已排序数据。
实际上,只要一条 SQL 语句需要进行排序操作,都会显示“Using filesort”,这并不表示就会有文件排序操作。