sql语句执行顺序:
from---> join---> on---> where---> group by---> avg,sum.... ---> having---> select---> distinct---> order by---> limit
存储过程优点:
存储过程是一组予编译的 SQL 语句,它的优点有:
允许模块化程序设计,就是说只需要创建一次过程,以后在程序中就可以调用该过程任意次。
允许更快执行,如果某操作需要执行大量 SQL 语句或重复执行,存储过程比 SQL 语句执行的要快。
减少网络流量,例如一个需要数百行的 SQL 代码的操作有一条执行语句完成,不需要在网络中发送数百行代码。
实际上尽量少用存储过程,因为存储过程难以调试和扩展
MySQL 存储过程的创建
CREATE PROCEDURE 存储过程名(参数列表) BEGIN SQL 语句代码块 END 查询user表中有多少用户demo: CREATE PROCEDURE proc1(OUT s int) BEGIN SELECT COUNT(*) INTO s FROM user; END
参数: MySQL 存储过程参数有三种类型:in、out、inout。
如果仅仅想把数据传给 MySQL 存储过程,那就使用“in”类型参数;如果仅仅从 MySQL 存储过程返回值,
那就使用“out”类型参数;如果需要把数据传给 MySQL 存储过程,还要经过一些计算后再传回给我们,
此时,要使用“inout”类型参数。
Mysql 调用储存过程
Set @n=1 //声明变量 Call procName(@n) //调用储存过程
索引
用到索引的地方:join、where、order by
索引是否起作用用explain查看,测试数据量小测试的sql可以抛弃索引。
ALTER TABLE <表名> ADD INDEX (<字段>); 例:
mysql> alter table t_name add index(field_name);
索引分类
-
普通索引(index):仅加速查询
-
唯一索引(unique index):加速查询 + 列值唯一(可以有null)
-
主键索引(primary key):加速查询 + 列值唯一(不可以有null)+ 表中只有一个
-
组合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并
-
全文索引(fulltext):对文本的内容进行分词,进行搜索
全文索引要用MATCH (col1,col2,...) AGAINST (expr [search_modifier])查询
约束
/*外键约束,父表一定要设置主键不然执行不成功*/
alter table 子表的数据表名 add foreign key(子表的外键名称) references 父表的数据表名称(父表的主键名称);
mysql 分库分表
分库分表有垂直切分和水平切分两种。
垂直切分:即将表按照功能模块、关系密切程度划分出来,部署到不同的库上。例如,我们会建立定义数据库 workDB、商品数据库 payDB、用户数据库 userDB、日志数据库 logDB 等,分别用于存储项目数据定义表、商品定义表、用户数据表、日志数据表等。
水平切分:当一个表中的数据量过大时,我们可以把该表的数据按照某种规则,例如 userID 散列,进行划分,然后存储到多个结构相同的表,和不同的库上。例如,我们的 userDB 中的用户数据表中,每一个表的数据量都很大,就可以把 userDB 切分为结构相同的多个 userDB:part0DB、part1DB 等,再将 userDB 上的用户数据表 userTable,切分为很多 userTable:userTable0、userTable1 等,然后将这些表按照一定的规则存储到多个 userDB 上。
应该使用哪一种方式来实施数据库分库分表,这要看数据库中数据量的瓶颈所在,并综合项目的业务类型进行考虑。如果数据库是因为表太多而造成海量数据,并且项目的各项业务逻辑划分清晰、低耦合,那么规则简单明了、容易实施的垂直切分必是首选。而如果数据库中的表并不多,但单表的数据量很大、或数据热度很高,这种情况之下就应该选择水平切分,水平切分比垂直切分要复杂一些,它将原本逻辑上属于一体的数据进行了物理分割,除了在分割时要对分割的粒度做好评估,考虑数据平均和负载平均,后期也将对项目人员及应用程序产生额外的数据管理负。在现实项目中,往往是这两种情况兼而有之,这就需要做出权衡,甚至既需要垂直切分,又需要水平切分。我们的游戏项目便综合使用了垂直与水平切分,我们首先对数据库进行垂直切分,然后,再针对一部分表,通常是用户数据表,进行水平切分。
单库多表 :
随着用户数量的增加,user 表的数据量会越来越大,当数据量达到一定程度的时候对 user 表的查询会渐渐的变慢,从而影响整个 DB 的性能。如果使用 mysql, 还有一个更严重的问题是,当需要添加一列的时候,mysql 会锁表,期间所有的读写操作只能等待。可以将 user 进行水平的切分,产生两个表结构完全一样的 user_0000,user_0001 等表,user_0000 +user_0001 + …的数据刚好是一份完整的数据。
多库多表 :
随着数据量增加也许单台 DB 的存储空间不够,随着查询量的增加单台数据库服务器已经没办法支撑。这个时候可以再对数据库进行水平区分。分库分表规则举例:通过分库分表规则查找到对应的表和库的过程。如分库分表的规则是 user_id 除以 4 的方式,当用户新注册了一个账号,账号 id 的 123,我们可以通过 id 除以 4 的方式确定此账号应该保存到 User_0003 表中。当用户 123 登录的时候,我们通过 123 除以 4 后确定记录在 User_0003 中。
mysql 读写分离
在实际的应用中,绝大部分情况都是读远大于写。Mysql 提供了读写分离的机制,所有的写操作都必须对应到 Master,读操作可以在 Master 和 Slave 机器上进行,Slave 与 Master 的结构完全一样,一个 Master可以有多个 Slave,甚至 Slave 下还可以挂 Slave,通过此方式可以有效的提高 DB 集群的每秒查询率.所有的写操作都是先在 Master 上操作,然后同步更新到 Slave 上,所以从 Master 同步到 Slave 机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave 机器数量的增加也会使这个问题更加严重。此外,可以看出 Master 是集群的瓶颈,当写操作过多,会严重影响到 Master 的稳定性,如果 Master 挂掉,整个集群都将不能正常工作。就得考虑分库了。 2. 当写压力很大的时候,就必须得进行分库操作。