mysql设计与开发

架构设计
表结构设计
索引
sql语句
1.表结构设计的核心思想是什么?
容量评估,性能优化,硬件升级,垂直拆分,水平拆分

2.有个大表为了一个查询(一天就查2次),领导要你建索引(索引空间大小有500G),
你怎么考虑,是建还是不建?建索引时要考虑哪些因素?

3.执行计划中有 filesort 就会进行磁盘文件排序吗(详细说明)?
Using filesort:当我们的Query 中包含ORDER BY 操作,而且无法利用索引完成排序操
作的时候,MySQL Query Optimizer 不得不选择相应的排序算法来实现。

数据库的范式
1NF):数据库表中的字段都是单一属性的,不可再分,这个单一属性由基本类型构成,包括整型、实数、字符型、逻辑型、日期型等
2NF):数据库表中不存在非关键字段 对任一候选关键字段 的部分 函数依赖
选课关系表为SelectCourse(学号, 姓名, 年龄, 课程名称, 成绩, 学分)
(学号, 课程名称) → (姓名, 年龄, 成绩, 学分)
3NF):在第二范式的基础上,数据表中如果不存在非关键字段 对任一候选关键字段 的传递 函数依赖 则符合第三范式。
所谓传递函数依赖,指的是如 果存在"A → B → C"的决定关系,则C传递函数依赖于A
学生关系表为Student(学号, 姓名, 年龄, 所在学院, 学院地点, 学院电话),关键字为单一关键字"学号"
(学号) → (所在学院) → (学院地点, 学院电话)即存在非关键字段"学院地点"、"学院电话"对关键字段"学号"的传递函数依赖

在商业环境中,绝大多数超越第3范式的设计都是不切实际的。 由范式的进阶来看,越高等级的范式所产生的表越多,
而在应用程序使用的过程中越多的表Join和查询造成的性能损耗的问题,甚至很多情况下为了兼顾性能和开发我们甚至要做一下反范式的操作

1 表字段类型选择
tinyint,int,bigint
decimal(m,n)
datetime,timestamp
varcahr(n)
utf8
表容量评估,数据归档评估

架构设计
读写分离,schema解耦,冷热数据分表

表结构设计:INNODB,auto increment primary key,comment
原则:只增不减,自增主键,主键不应该被修改,不用字符串做主键,拆开宽表
varchar(500),控制单表数据量,越短越好
控制列数量
表字段数少而精
IO高效、全表遍历、表修复快、 提高并发、 alter table快
单表多少字段合适
单表1G体积500W行评估
顺序读1G文件需要N秒
单行不超过200Byte
单表不超50个纯INT字段
单表不超20个CHAR(10)个字段
单表字段数上限控制在20-50个
update_time timestamp not null default current_timestamp on update current_timestamp
default 0,不使用default null
default ''
不使用text,blob
索引字段定义not null
禁用外键
数字型VS字符型索引:更高效、查询更快、占用空间更小
示例:
mysql> create table yhq_t11(id int unsigned);
mysql> insert into  yhq_t11 values (INET_ATON('127.0.0.1'));
mysql> select * from  yhq_t11;
| id |
+------------+
| 2130706433 |
mysql> SELECT INET_NTOA(id) from  yhq_t11;
| INET_NTOA(id) |
存储精确浮点数必须使用DECIMAL替代FLOAT和DOUBLE
尽可能不要使用TEXT、 BLOB
1) 索引排序问题,只能使用max_sort_length的长度或者手工指定ORDER BY SUBSTRING(column,
length)的长度来排序
2) Memory引擘不支持text,blog类型,会在磁盘上生成临时表
3) 可能浪费更多的空间
4) 可能无法使用adaptive hash index
5) 导致使用where没有索引的语句变慢
6) Varchar的性能会比text高很多
为什么不要default NULL
索引不会包括NULL值。影响索引的统计信息,影响优化器的判断。
复合索引中只要有一列含有NULL值,那么这一列对于此复合索引就是无效的, NULL字段很难查询优化
(NULL字段无法索引) 。
a)如果null字段被索引,需要额外的1字节作为判断是否为NULL的标志位“需要mysql内部进行特殊处理)
b)使索引,索引统计,值的比较变得更复杂
c)可用0,” 代替
d)如果是索引字段,一定要定义为not null
不在数据库里存图片

索引
1.唯一键不和主键重复。
2.不要修改聚焦索引。
3.使用EXPLAIN判断SQL语句是否合理使用索引,尽量避免extra列出现: Using File Sort, UsingTemporary。
4.索引不是越多越好,尽量合并索引,合理创建联合索引(避免冗余)。
5.合理利用覆盖索引,结合核心SQL优先考虑覆盖索引。
6.不要修改聚集索引(主键)
7.不要给选择性低的字段建单列索引, MySQL对索引的过滤性有要求,如果过滤性太低, MySQL会放弃使用
例如:不要给“性别”列创建索引。
8.不要使用外键约束
9.字符类型字段尽量使用前缀索引, 太长的索引不仅影响写入性能,而且使用性能也差
10.能不加的索引尽量不要加
综合评估数据密度和数据分布
最好不超过字段数20%

sql语句
慎用count(*)
Count(*)的资源开销大,尽量不用少用!
实时统计:用memcache,双向更新,零晨跑基准
非实时统计:尽量用单独统计表,定期重算
select /*+first_rows(1)*/ count(*) from t1 where rownum<2;
比如,有些应用,只是想看看我表里是否有数据,或者满足某个条件的,是否有数据。
first_rows来作。
sql语句尽可能简单
拒绝大SQL,拆解成多条简单SQL
减少锁时间
用上更多CPU
简单SQL缓存命中率更高
INSERT语句使用batch提交
降低CUP,不在数据库做运算
select id*16 from  yhq_t1;
上面的语句放在MySQL不起眼,不是很明显,这些运算没必要放在数据库里,数据库尽量做到简
单,数据库就检索数据,对这些数据的加工就放在应用层。
让数据库多做她擅长的事:
1)尽量不在数据库做运算
2)复杂运算移动程序端CPU
3)尽可能简单应用MySQL

必须使用绑定变量, 避免常量的直接引用
频繁的硬解析会影响数据库性能
ibatis中,所有的 ##都是绑定变量

posted @ 2019-01-11 10:12  春困秋乏夏打盹  阅读(299)  评论(0编辑  收藏  举报