日常编程中的小技巧以及注意点(四)

    之前写过一篇《日常编程中的小技巧以及注意点(三)》,感兴趣可以查看。


<1>【MySQL】字段允许适当冗余,以提高查询性能,但必须考虑数据一致。

    冗余字段应遵循:

  1. 不是频繁修改的字段。
  2. 不是varchar超长字段,更不能是text字段。

正例:商品类目名称使用频率高,字段长度短,名称基本一成不变,可在相关联的表中冗余存储类目名称,避免关联查询。


<2>【MySQL】当单表行数超过500万行或者单表容量超过2GB时,才推荐进行分库分表

说明:如果预计三年后的数据量无法达到这个级别,请不要在创建表时就分库分表。


<3>【MySQL】设置合适的字符存储长度,不但可以节约数据库表空间和索引存储,更重要的是能够提升检索速度

正例:见下表,其中无符号值可以避免误存负数,且扩大了数据的表示范围。

对象 年龄区间 类型 字节 表示范围
150岁之内 unsigned tinyint 1 无符号值;0至255
数百岁 unsigned smallint 2 无符号值;0至65535
恐龙化石 数千万年 unsigned int 4 无符号值;0至约42.9亿
太阳 约50亿年 unsigned bigint 8 无符号值;0至约

<4>【MySQL】业务上具有唯一特性的字段,即使是多个字段的组合,也必须建成唯一索引

说明:不要以为唯一索引影响了insert速度,这个速度损耗可以忽略,但会明显提高查找速度;另外,即使在应用层做了非常完善的校验控制,只要没有唯一索引,根据墨菲定律,必然有脏数据产生。


<5>【MySQL】超过三个表禁止join。需要join的字段,数据类型必须绝对一致;当多表关联查询时,保证被关联的字段需要有索引

说明:即使双表join也要注意表索引、SQL性能。


<6>【MySQL】建组合索引的时候,区分度最高的在最左边

正例:如果where a=? and b=?,a列几乎接近于唯一值,那么只需要单建idx_a索引即可。

说明:如存在非等号和等号混合判断条件,在建索引时,请把等号条件的列前置。如where a>? and b=?,那么即使a的区分度更高,也必须把b放在索引的最前列。


<7>【MySQL】count(distinct col)计算该列除NULL外的不重复行数。注意,count(distinct col1, col2),如果其中一列全为NULL,那么即使另一列有不同的值,也返回为0


<8>【MySQL】当某一列的值全为NULL时,count(col)的返回结果为0,但sum(col)的返回结果为NULL,因此使用sum()时需注意NPE问题

正例:可以使用如下方式来避免sum的NPE问题:SELECT IF(ISNULL(SUM(g)), 0, SUM(g)) FROM table;


<9>【MySQL】使用ISNULL()来判断是否为NULL值

说明:NULL与任何值的直接比较都为NULL。

  1. NULL<>NULL的返回结果是NULL,而不是false。
  2. NULL=NULL的返回结果是NULL,而不是true。
  3. NULL<>1的返回结果是NULL,而不是true。

<10>【MySQL】不得使用外键与级联,一切外键概念必须在应用层解决

    说明:以学生和成绩的关系为例,学生表中的student_id是主键,那么成绩表中的student_id则为外键。如果更新学生表中的student_id,同时触发成绩表中的student_id更新,即为级联更新。外键与级联更新适用于单机低并发,不适合分布式、高并发集群;级联更新是强阻塞,存在数据库更新风暴的风险;外键影响数据库的插入速度。


<11>【MySQL】数据订正(特别是删除、修改记录操作)时,要先select,避免出现误删除,确认无误才能执行更新语句


<12>【MySQL】in操作能避免则避免,若实在避免不了,需要仔细评估in后面的集合元素数量,控制在1000个之内


<13>【MySQL】在表查询中,一律不要使用*作为查询的字段列表,需要哪些字段必须明确写明

说明:1.增加查询分析器解析成本。

           2.增减字段容易与resultMap配置不一致。

SELECT *增加很多不必要的消耗(CPU、IO、内存、网络带宽);增加了使用覆盖索引的可能性;当表结构发生改变时,前断也需要更新。所有要求直接在select后面接上字段名。


<14>【MySQL】sql.xml配置参数使用:#{},#param#,不要使用${},此种方式容易出现SQL注入


<15>【MySQL】不要写一个大而全的数据更新接口

    传入为POJO类,如果不管是否为自己的目标更新字段进行update table set c1=value1, c2=value2, c3=value3;是不对的。执行SQL时,不要更新无改动的字段,一是容易出错,二是效率低,三是会增加binlog存储。


<16> 类在设计与实现时要符合单一原则

说明:单一原则是最易理解却又最难实现的一条规则,随着系统的演进,工程师很多时候会忘记类设计的初衷。


<17> 在系统设计阶段,共性业务或公共行为抽取出来公共模块、公共配置、公共类、公共方法等,在系统中不应出现重复代码的情况

说明:随着代码的重复次数不断增加,维护成本呈指数级上升。


<18> 尽量早释放无用对象的引用

    大部分时,方法局部引用变量所引用的对象会随着方法结束而变成垃圾,因此,大部分时候程序无需将局部引用变量显式设为null。

    例如:

public void test() {
    Object obj = new Object();
    //do something...
    obj = null;
}

    上面这个就没必要了,随着方法test()的执行完成,程序中obj引用变量的作用域就结束了。但如果是下面这样的情况:

public void test() {
    Object obj = new Object();
    //do something...
    obj = null;
    //执行耗时,耗内存的操作;或调用耗时,耗内存的方法
    //do something...
}

    这时候就有必要将obj赋值为null,可以尽早的释放对Object对象的引用。


<19> 巧判奇数

    判断一个数是否是奇数,你可能会这样做:

if (n % 2 == 1) {
    doSomething();
}

    不过我们用与或运算的话会快很多。例如判断是否是奇数,我们就可以把n和1相与了,如果结果为1,则是奇数,否则就不会。即:

if (n & 1 == 1) {
    doSomething();
}

<20>【MySQL】SQL语句中IN包含的值不应过多

    MySQL对于IN做了相应的优化,即将IN中的常量全部存储在一个数组里面,而且这个数组是排好序的。但是如果数值较多,产生的消耗也是比较大的。再例如:

select id from t where num in(1,2,3)

对于连续的数值,能用between就不要用in了;再或者使用连接来替换。

猜你喜欢

转载自blog.csdn.net/weixin_30342639/article/details/86759277
今日推荐