数据库-你可能忽略的东西

数据库的使用你可能忽略了这些

https://www.cnblogs.com/joylee/p/7768457.html

数据库的管理是一个非常专业的事情,对数据库的调优、监控一般是由数据库工程师完成,但是开发人员也经常与数据库打交道,即使是简单的增删改查也是有很多窍门,这里,一起来聊聊数据库中很容易忽略的问题。

字段长度省着点用
先说说我们常用的类型的存储长度:

列类型 存储长度
tinyint 1字节
smallint 2字节
int 4字节
bigint 8字节
float 4字节
decimal(m,d) 0-4字节
datetime 8字节
timestamp 4字节
char(m) m个字节
varchar(m) 可变长度
text 可变长度
很明显,不同的类型存储的长度有很大区别的,对查询的效率有影响,字段长度对索引的影响是很大的。

字符串字段长度都差不多的,可以预估长度的,用char
字符串长度差异大,用varchar,限制长度,不要浪费空间
整型根据大小,选择合适的类型
时间建议用timestamp
建议使用decimal,不建议使用float,如果是价格,可以考虑用int或bigint,如1元,存储的就是100
放弃uuid(guid)的使用
不管是uuid,还是guid,使用的时候都是为了避免同时生成重复的ID,但是建议考虑其他方案,原因如下:

uuid没有顺序
uuid太长
uuid规则完全不可控
推荐的方案用bigint(首选),或者char来存储,生成方式参考snowflake的算法,有顺序、长度固定、比uuid更短,当然,也几乎不会重复。

大表减少联表,最好是单表查询
单表查询的优势很多,查询效率极高,便于分表分库扩展,但是很多时候大家都觉得真正实现起来不太现实,完全失去了关系数据库的意义,但是单表的性能优势太明显,一般总会有办法解决的:

合理的冗余字段
配合内存数据库(redis\mongodb)使用
联表变多次查询(下文会有说明)
如果考虑都后期数据量大,需要分表分库,就应该尽早实时单表查询,现在的数据库分表分库的中间件基本都无法支持联表查询。即使如mycat最多支持两个表的联表查询,但是也有很明显的性能损耗。

索引的正确处理方式
索引的优势这里就不多说了,索引使用不当会有反效果:

数据量很小的表,不需要索引
一个表的索引不宜过多,建议最多就5个,索引不可能满足所有的场景,但是了个满足绝大部分的场景
mysql 和 sqlserver的索引差别还挺大的,需要注意。例如:
mysql索引字段的顺序对性能有很大影响,sqlserver优化过,影响很小
多查几次比联表可能要好
提出这个方案相信会得到很多人的反对,但是我相信这个结论还是非常适合数据量大的场景。多查几次数据库有这么几个弊端:

增加了网络消耗
增加了数据库的连接数
其实,这两个问题在现在基本都可以忽略的,数据库和应用的连接基本都是内网,这个网络连接的效率还是很高的。数据库对连接池的优化已经比较成熟了,连接数只要不是太多,影响也不会太严重,但是多查几次的优势却很多:

单表效率更高
便于后期扩展分表分库库
有效利用数据库本身的结果缓存
减少锁表,联表会锁多个表
当然,多查几次这个度一定要把握。千万不要在一个循环里面查询数据库。我们也应该尽量减少查询数据库的次数。我们可以接受1次查询变2次查询,如果你变成10次查询,那就要放弃了。
举个例子:
查询商品的时候,需要显示分类表的分类名

select category.name,product.name from product inner join category on p.categoryid=category.id
建议的方式:

select categoryid,name from product
select categoryname from category where categoryid in ('','','','')
当然,你可以再优化一下,查询分类名之前,对product的categoryid排序一下,这样速度更快。因为我们前面已经用snowflake生成了有顺序的主键了。
补充一下,in的效率并不是你想象的那么慢,如果保持在100个节点(很多书籍介绍1000个节点,我们保守一点),性能还是很高的。

尽量使用简单的数据库脚本
很多用过 .net Entity Framework 的人都说这个框架太慢,其实慢主要是两点:错误的使用延迟加载(外键关联)、生成SQL编译太慢。Entity Framework生成的SQL脚本有太多没用的东西,导致编译太慢。
数据库脚本尽量使用简单的,不要用太长的一个SQL脚本,会导致初次执行的时候,编译SQL脚本花费太多的时间。

尽量去避免聚合操作
聚合操作如count,group等,是数据库性能的大杀手,经常会出现大面积的表扫描和索表的情况,所以大家能看到很多平台都把数量的计算给隐藏了,商品查询不去实时显示count的结果。如淘宝,就不显示查询结果的数量,只是显示前100页。
避免聚合操作的方法就是将实时的count计算结果用字段去存储,去累加这个结果。当然,也可以考虑用spark等实时计算框架去处理,这种高深的技术,不在此次讨论范围内。(PS:主要是我也不懂)

总结
程序的优化很多时候都是一些细节的问题,更应该注意平时的积累,阿里SQL的规范有很多可以吸取的地方,以上也是自己工作中的一些总结,欢迎大家补充。

https://www.cnblogs.com/joylee/p/9521741.html

前言
之前写过一篇文章《数据库的使用你可能忽略了这些》,主要是从一些大家使用使用时容易忽略的地方,如:字段长度、表设计等来说明,这篇文章同样也是这样的主题,只是从另外的几个方面来说说数据库使用中,容易忽略,导致入坑的地方。

合理预估数据量
在数据库进行表设计的时候,就应该评估可能产生的数据量,数据量会对整个开发和代码的健壮性有很大的影响。开发一个数据量万级别、十万级别、百万级别、千万以上级别数量的应用,在开发思路、技术选型、架构都能都要很大的差别。
基本上的我的原则是:

万级别的数据库,可以随意一点,SQL编写有好的习惯;
十万级别,注意索引,注意联表性能;
百万级别,尽量减少联表,尽量不要做汇总查询,如查总数 ;
千万以上级别,除缓存之外,使用分表分库 ;
很多系统因为在设计表的时候,没有很好的预估的后期系统的发展,导致上线不久就出现无法支撑的情况,代码上太多的联表查询,不在乎基础的SQL性能,导致数据库的瓶颈很快就显现出来,不得不重构系统。设计数据库的时候,一定是基于业务进行设计的,对业务的发展有一定的预估,看得长远一点。

合理预估并发访问量
数据库有天然的瓶颈,就是并发量。我们一般会通过缓存来减少数据库的并发连接,以及对数据库的操作,数据库的并发,不是只有大型平台才会遇到,很多中小平台其实也会面临这样的问题,例如:

循环进行数据库的操作
这个问题,上一篇文章我也提到过,不要在循环里进行数据库的操作,这个会直接导致数据库连接数暴增,影响非常严重。虽然是个比较低级的问题,但是出现的概率其实是非常高的,在我身边看到很多很多这种案例了,这种问题,就是需要程序员自己本身避免这些问题,当然,也可以通过一些手段去监控,找到这些问题,只是会比较麻烦一点。

业务本身的高频次数据请求
其实有些业务,即使是中小型的平台,也会有高并发请求数据库的情况,常见的例子如:日志。例如,我们需要抓取到所有人的操作日志,或者所有模块的加载时间,并且持久化保存。如果,当初选型通过Mysql去记录这些数据,那么就很容易遇到高并发的问题。这种就是属于选型的错误了。

数据库对高并发的处理一直是短板,所以应该尽量避免高并发的数据库操作,查询通过缓存处理,增删改这可以通过MQ或者Kafka这样的工具异步进行处理,如果对数据库的结构化要求不高,则可以用hbase或者hive进行数据库的保存。

数据库线程池的合理使用
现在数据库的操作都是使用线程池的,线程池主要是用来控制数据库的连接数,其实连接池是不属于数据库范畴,但是,一般我们使用和数据库结合非常紧密,所以在这里一并说明。
一般线程池都会有这样的几个参数:

参数 说明
最小连接数 不管是否有数据库的操作,这几个连接都会一直存在,
最大连接数 允许的最大的连接数,如果超过了这个数据,则无法申请连接,只能等待,或者异常
回收时间 多长时间会对所有的连接进行一次断开,然后重新连接。
释放时间 多长时间没有进行操作的连接,会释放
基本所有的连接池都会有这几个参数,可能不同的连接池参数名不同,但是作用是一样的。 这里我们重点说一下最大连接数,这个是很容易忽略的一个设置。
很多人设置最大连接数的时候,喜欢设置的很大,例如设置为5000,但是一般mysql的数据库一个实例连接默认才1000,连接数超过这个了数据库也无法处理,设置的再大其实是没用的。

服务器数量 * 最大连接数 < 数据库最大连接数

而且,这还是在一个实例,一个数据库的情况下,至于多个数据库:
我建议

服务器数量 * 最大连接数 * 数据库数量 < 数据库最大连接数

如果单个数据库占用了太多的数据库连接,会影响到其他数据库,导致其他数据库也无法使用。
当然,这个值大家可以根据业务去进行合理的估算,高频的业务分配多一点,低频的业务分配少一点。不要盲目的一味设置连接池的最大值。

总结
如今,虽然各种各样的存储方式出现,但是关系数据库一直是我们系统的最重要的组成部分,尽量不要过早暴露数据库应对并发的短板,设计数据库和操作数据库在我们的开发中应该是一件很神圣的事情,认证对待关系的数据库的每一个操作才是明智之举。

扩展阅读:
数据库的使用你可能忽略了这些
学会数据库读写分离、分表分库——用Mycat,这一篇就够了!

猜你喜欢

转载自www.cnblogs.com/Leo_wl/p/9564568.html