Upload
beenyoung-lee
View
4.715
Download
7
Embed Size (px)
DESCRIPTION
面向开发人员的演讲稿,侧重点在于使听众加深对数据库一些细节设计的认识,提高对象设计的能力和质量,尤其强调一些常识性、必须遵守的准则。PPT中主要以MySQL的InnoDB引擎为主,讲解时穿插对比介绍了ORACLE相应的对象/实现方式/功能~~
Citation preview
http://weibo.com/junsansi
君三思 2012-01
ORACLE & MYSQL
数据库模式设计漫谈
粒度 各有不同
每一种粒度都大有讲究
SCHEMA/DB
数据库
TABLE 表
INDEX 索引
从数据库开始谈起
核心:SHARDING、SHARDING、还是SHAREDING
想出? 哪有那么容易!
想进? 要进也进不来!
随便放行不行?
插呗~
随便插呗~
随便找地方插呗~
…………….
拆时怎么办?
• 垂直拆分
• 水平拆分
数据分片存储
垂直拆分(SCALE UP)
• 按业务 • 按类型
水平拆分(SCALE OUT)
• 按时间 • 按KEY HASH
数据拆分(SHARDING)
天天打交道的表和列
核心:适度、适量
选择存储引擎:
MyISAM vs InnoDB
选择字符集:
GBK vs UTF8
关键因素!
一经设定
影响深远
• 控制字段数量(10列? 30列? 50列?)
• 控制记录数量(10w? 100w? 1000w?)
• 每个表都必须定义主键
• TEXT/BLOB等大字段单独存储
表设计原则
选择数据类型(1) – 整型
选择数据类型(2) – 字符型
选择数据类型(3) – 日期型
选择数据类型(4) – 综述
必须正确理解的几个细节:
• INT(1) 的精度?
• CHAR(4) 占用的空间?
• VARCHAR(255)和VARCHAR(256) 占用的空间?
• TINYTEXT最大支持的字符数?
• TIMESTAMP值的范围?
• …...
« 每个字段尽可能设置DEFAULT值;
« 尽可能使用数值型存储,如IP地址;
« 数值类型定义时声明UNSIGNED;
« 主键(自增列)使用INT类型;
« 日期和时间使用TIMESTAMP类型;
« 尽量不使TEXT/BLOB字段,如有可拆分成行处理;
« 列名不要与系统保留关键字冲突,如time,date等;
核心:遵循够用就好的原则;
列设计原则(1)
BAD DESIGN:
ID BIGINT AUTO_INCREMENT
CHAR(10) DEFAULT NULL
NOT NULL DEFAULT ‘’
`CREATE_DATE` timestamp NOT NULL default CURRENT_TIMESTAMP
on update CURRENT_TIMESTAMP
`LAST_UPDATE_DATE` timestamp NOT NULL default ‘0000-00-00
00:00:00’
……
列设计原则(2)
索引:查询语句的关键因素
核心:HOW、WHY、 WHEN
要向5号楼的702和9号楼的501发快递,怎么办?
快递员的烦恼
要是有个楼层图就好了!
快递员的烦恼(2)
索引的类型
InnoDB引擎支持的索引:
• 单列索引
• 主键/唯一索引
• 复合索引
• 前缀索引
InnoDB索引结构
可能用到索引的操作
• 查询语句中有WHERE条件;
• 多表关联查询;
• 执行MIN()、MAX()类型聚集函数;
• 执行ORDER BY对结果集排序;
• 查询的列本身就在索引内;
提示:当存在多个可用的索引时,MySQL会选择最小的那个;
索引的特点
优点:
• 提高查询速度
• 提高内存使用效率
缺点:
• 降低写效率
• 占用更多磁盘空间
什么情况下 不用索引 效果更佳?
不是所有情形都适合使用索引
索引不是越多越好
» 表中必须创建 主键,主键应尽可能的短小
» 索引键长度不要超过30字节
» “WHERE”用不到的列不建索引
» 非特殊条件、STATUS/SEX等低异相值列不建索引
» “NULL”列不建索引
» 查询条件有多列时尽可能创建复合索引
索引要点
BAD-DESIGN 找问题
CREATE TABLE `xxx_xxxx` ( `uid` bigint(20) NOT NULL COMMENT '主站用户id ', `useriden` char(17) DEFAULT NULL COMMENT '用户uiden', `username` char(64) DEFAULT NULL COMMENT '用户名 ', `regdate` int(10) DEFAULT NULL COMMENT '注册时间', `password` char(32) DEFAULT NULL COMMENT '密码', `email` char(255) DEFAULT NULL COMMENT 'email 依赖', `status` tinyint(1) DEFAULT NULL COMMENT '0冻结;1正常', `image` char(255) DEFAULT NULL COMMENT '头像 ', `bigimage` varchar(255) NOT NULL, `regip` char(15) DEFAULT NULL COMMENT '注册IP ', `lastvisit` int(10) DEFAULT NULL COMMENT '最后访问时间', `lastip` char(15) DEFAULT NULL COMMENT '最后访问IP', `loginstatus` tinyint(1) NOT NULL DEFAULT '0' COMMENT '登录状态', `cas_ticket` varchar(255) NOT NULL COMMENT '登录校验ticket', `is_super_admin` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否是超级管理员', `type` tinyint(1) NOT NULL DEFAULT '1' COMMENT '1普通用户、2普通行家', PRIMARY KEY (`uid`), KEY `loginstatus` (`loginstatus`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户表'
? 这只是开始... 细节并未完全呈现!
» 执行计划
» 慢查询日志
» 查询缓存
» 语句改写
» ……
与性能密切 关联 的话题
您的消息是什么? Q&A