架构
- 一般把读取的请求放在缓存(Redis),而更新请求放在数据库
触发器
一定要慎用目前主流DBMS都支持的触发器功能,一方面由于触发器的性能开销较大,另一方面,触发器的多级触发不好控制,容易发生错误。
视图
为了在数据库和应用程序代码之间提供另一层抽象,可以为应用程序建立专门的视图而不必非要应用程序直接访问数据表。这样做还等于在处理数据库变更时给你提供了更多的自由。
存储过程
不要写,尽量将业务逻辑放在应用服务中。
分库分表
水平切分
水平切分的切分标准可以按照数据范围分,比如1-100万一个表,100万-200万又是一个表;也可以按照时间顺序来切分,比如一年的数据归到一张表中等;也可以按照地域范围来分,比如按照地市来分,每个或多个地市一个库等;也可以按照某种计算公式来切分,比较简单的比如取模的方式,如根据用户id进行水平切分,可通过对ID被2取模,然后分别存放在不同的表中,这样关联时也非常方便。公司著名的凤巢拆库就是采用取模方式进行的拆分。
字段属性
- datetime和timestamp能保存同样类型的数据:日期和时间,精度为秒。然而,timestamp使用的空间只有datetime一半,还能保存时区,拥有特殊的自动更新能力。
- 使用整数来保存IP地址。
- 有符号(signed)和无符号(unsigned)类型占用的存储空间是一样的,性能也一样。因此可以根据实际情况采用合适的类型。
- MySQL还可以对整数类型定义宽度,比如int(11)。这对于大多数应用程序都是没有意义的:它不会限制值的范围,只规定了MySQL交互工具(如命令行客户端)用来显示字符的个数。对于存储和计算,int(1)和int(20)是一样的。
- char是固定长度的。MySQL总是为特定数量的字符分配足够的空间。当保存char值的时候,MySQL会去掉任何末尾的空格。
关于索引
数据查询只能用到一个索引,不过这个只是说的是单表查询,联表查询实际上每个表都可以用到其独立的索引
有些时候索引并不会用到,比如
where key like ‘keyword%‘:这里可以用到key索引
where key like ‘%keyword%‘:这里用不到key的索引- 适当建立复合索引:
前几天看了“caoz的梦呓”的文章《如何应对并发(1) - 关于数据索引》,理解了建立复合索引所需要考虑的一些东西,顺序不同效率也有很大的不同。
‘SELECT * FROM user where area = ‘$area’ order by lastlogin desc limit 30;’
如果只把area当做索引,那么数据库会把符合这个area的所有结果都拿出来,然后按照lastlogin来进行排序;
如果只把lastlogin做为索引,那么数据库会从最后一条开始往前遍历,每条都会对比area,直到数出30条
如果lastlogin+area建立符合,和单独lastlogin索引是一样的
如果area+lastlogin,把两个字段拼接然后排好序后,看这条SQL在这个数列中查询的提现,所命中的完全是连续的30条,仅仅遍历30条索引即可
我最先以为简历复合索引也会是先查找出area,再拿出来排序哟,但其实索引都是预先排好了的,这里就相当于先按照area排序,area相同的再按照lastlog
in进行排序,这样,只要找到area,然后取前面30条就可以了,就像电话簿一样,先找姓氏,姓氏相同的也会按照名排好序的。
- 适当建立复合索引: