1.数据库设计那点事
需求分析:前期的准备工作,分析的越完善,后期越轻松
逻辑设计:ER图:实体-联系图
第一范式:数据表中每一列都不可在分
第二范式:数据库中每一列都必须和主键完全相关,而不同只与一部分相关(联合主键)
第三范式:数据库每一列必须和主键直接相关
B C范式:任何字段都不能传递依赖候选关键字
物理设计:
数据库:MYSQL
存储引擎:
MYISAM:不支持事务,外键,访问速度快,以select,insert为主,全文索引
.frm存储表定义 MYD存储数据 MYI存储索引 数据索引不同目录,分配IO
INNODB:自动列增长,外间约束,支持事务,更新密集(高并发)
事务隔离级别,热备份,首选
MEMORY:内存 目标数据小,使用频率高 数据临时(立即使用) 数据遗失无影响
MERGE: MYISAM聚合 日志文件
数据类型:数值 tinyint 1 (-128-127)
smallint 2 -32768-32767
int 4
float m,d 4
double 8
decimal
字符 char n 255 n个字符
vachar 65535
日期 date 3
time 3
datetime 8
timestamp 4
反范式:允许适量的数据冗余,空间换时间
维护优化:
维护数据字典
维护索引
2.与MYSQL的零接触
主键约束 PRIMARY KEY 自带唯一约束
唯一约束 UNIQUE 可以有多个
默认约束 DEFAULT
外键约束 Foreign key REFERENCES
非空约束 NOT NULL
存储过程 编译后存储在数据库中
CREATE Procedure 过程名(过程参数)
mysql> DELIMITER //
mysql> CREATE PROCEDURE proc1(OUT s int)
-> BEGIN
-> SELECT COUNT(*) INTO s FROM user;
-> END
-> //
mysql> DELIMITER ;
自定义函数 DELIMITER $$
DROP FUNCTION IF EXISTS `onlineFunction`$$
CREATE FUNCTION `onlineFunction`(rrrr VARCHAR(50)) RETURNS VARCHAR(255)
BEGIN
IF(rrrr=online) THEN RETURN 上线;END IF;
END$$
DELIMITER ;
子查询 select * from president where birht=(select min(birth) from presidnet);
左连接 在左表中加入,右表满足条件的行,左表没有的列加null
右连接 在右表中加入,左表满足条件的行,右表没有的列加null
内连接 两个表的交集,没有两表单独存在的数据
语句;CREATE TABLE TAB-NEW LIKE TAB-OLD 使用旧表创新表
CREATE INDEX INDEX-NAME ON TABLENAME 创建索引,不可改,只能删除
CREATE VIEW VIEWNAME AS SELECT QUERY 创建视图
SELECT TOP 0 * INTO TAB1 FROM TAB 复制表
3.性能优化之MYSQL优化
SQL语句优化 SHOW VARIABLES LIKE '%QUERY%'; 开启慢查日志
mysqldumpslow pt-query-digest; 慢查日志分析工具
查询次数多且每次查询占用时间长的SQL
IO大的SQL 分析慢查日志
未命中索引的SQL
分析SQL查询的执行计划 explain工具
MAX()优化 使用索引
COUNT()优化 SELECT COUNT(TIME=2006 OR NULL) AS 2006,COUNT(TIME=2007 OR NULL)AS 2007 FROM TAB
子查询优化
GROUP BY优化 优化为使用join查询,注意数据重复
索引优化 在WHERE从句 ORDER BY从句 GROUP BY从句 ON从句出现的列
索引字段越小越好 合适的列建立索引
离散度大的列放在前面,2个索引,范围大的前面
重复索引 PRI KEY UNIQUE 索引优化
冗余索引 已经有索引,无需再来索引
4.最佳实践
开启查询缓存 为每一张表设置ID
EXPLAIN查询语句 尽可能使用NOT NULL
只要一行数据时,使用limit 1 PREPARED STATEMENT
为搜索字段建立索引 把IP地址存为unsigned int
在JOIN表的时候,相同类型的字段,将其索引 固定长度的表会更快
千万不要ORDER BY RAND() 拆分大的DELETE和INSERT语句
避免SELECT * 使用ORM