明天想跟大家聊聊数据库层面上的事

:明天聊的数据库都特指关系型数据库

01、数据库抉择

之前发了一张我可能要在austin我的项目上引入哪些技术栈的图,好多人问我分布式配置核心为什么不抉择Nacos,而是用Apollo。却没人问我为什么数据库抉择MySQL。

说起来MySQL,在网上看到的各类Java教程,简直都是应用MySQL作为数据库。日常在群里聊各种数据库上的问题,也差不多都是MySQL,只有个别的可能用PostgreSQL和Oracle或其余

就连我在面试的时候,我也没被面试官问过:“你的数据库为什么抉择MySQL啊?这块技术选型是怎么样的”

看到这里,是不是感觉我有答案了?其实我也没有。写到一半的时候发现我也说不出啥比拟好的理由...既然我不晓得,于是我就去看看人家是怎么说的。

总结起因可能是:

  • 后期MySQL收费开源易用,从泛滥厂商中硬生生搞出了生态。有了生态,很难就被干掉了。(最次要的
  • 互联网用MySQL就是用来存数据“低成本疾速的数据存储插入计划”,要求也绝对没那么高(这条我前面会具体聊聊
  • 很多时候对某技术选型并非是技术起因

而我,我只会MySQL。我在生产环境下只用过MySQL,当年我还是小白的时候接触过Oracle,但当初也根本忘得差不多了。

很多时候对某技术选型并非是技术起因(我是懒狗,我抵赖了)。近几年PostgreSQL很火,据说很多中央都比MySQL要好,感兴趣的小伙伴能够把austin我的项目的MySQL替换为PostgreSQL

对数据库选型感兴趣的大哥们也能够找点材料持续查阅材料,也很欢送在评论区输入下本人的教训,这种话题探讨我感觉还是蛮有意思的。

跟着我一起做austin我的项目的小伙伴应该对关系型数据库都有所理解了,这里的根底我就不开展讲述了。对MySQL感兴趣或者筹备要面试的同学,能够看看我《对线面试官》系列的MySQL章节(在各大博客平台中受到了不错的反馈)

02、ORM框架抉择

记得几年前我刚接触数据库和Java的时候,那时候要用JDBC连贯数据库来操作数据,我就很不解:明明我能够通过各种的数据库客户端就能对数据进行操作,为啥我要用JDBC,好麻烦啊!

至于为什么会有这种疑难,我也不了解我过后是怎么想的(哈哈哈哈)。起初想通了当前,也学习了很多在程序上“简化JDBC模板”的姿态(DBUtils/Hibernate/Spring JDBC/Mybatis/SpringData JPA)

我在生产环境中接触过的都是Mybatis,但这一次我在asutin我的项目中决定应用SpringData JPA作为ORM框架。

03、应用数据库的教训

这两年我是呆在互联网公司下班的,我就来聊下我集体所接触到的货色,分享下我的认识。

一般来说,每个业务团队保护着本人的数据库(一个业务团队可能就有好几个库),当咱们须要某一个团队的相干数据时,团队会提供对应的RPC接口给公司外部业务应用。

这意味着数据逻辑对调用业务方而言,是通明的(调用业务方不须要关注其余团队数据库的任何信息,无论是数据库表设计还是具体的字段)。

这个益处是显然地:要某团队的业务数据,只有找到他们提供的接口就完事了。作为需求方,只须要调个接口就能拿到本人想要的数据。

回到数据库外部存储自身,咱们会尽可能将表结构设计得更简略:在很多状况下,都会放弃数据库三大范式来设计表。

举个很简略又可能不太失当的场景:一个作者可能会写多篇文章(意味着多篇文章会属于同一个作者) author:content(1:N)

那在初学的时候,可能有的教程会这样设计:author表content表autor_content_mapping表

然而,咱们在理论中生产环境中很有可能是不设计这种关联表,而是间接把相干字段冗余在一张表里。这样在查问的时候,就能间接通过一张表查到对应的信息了,不必进行多层关联

如果按下面的构造进行查问:比方我要查到某一篇文章的作者根本信息,那我此时的动作是:

  1. 关联author_content表查到文章的authorId
  2. 通过authorIdauthor表查到作者的根本信息

如果我把authorId间接存到content表中,那就意味着少了去author_content表查问了。

:这里我不是说让你们把所有的信息都存在一张表里,一张表里有上百个字段,千万不要误会我的意思!

说起关联,又有一个能聊的话题:是否join(这个话题我已经在我的交换群中聊过,不过也是各抒所见吧)。我在以前公司接触到的我的项目,在mapper.xml中都看不到join的身影,我写join只在hive写统计脚本的时候用到。

【强制】超过三个表禁止 join。须要 join 的字段,数据类型必须相对统一;多表关联查问时,保障被关联的字段须要有索引。

阐明:即便双表 join 也要留神表索引、SQL 性能。

我总结了一份:mysql性能优化和高可用架构实战,点此收费下载

喜爱用join的会通知你:我写join会让代码变得更简略。查数据太麻烦了,要查的数据会存到多张表里,间接在用join开发效率是最快的!

而我,我是反对在代码里写业务逻辑的。所有都是单表查问,在程序代码中对数据进行关联(数据库的JOIN无能到的事,在程序上肯定无能失去)。这样的益处就在于:SQL简略,SQL易复用,SQL易优化

在绝大数状况下,咱们的接口瓶颈都是来源于「数据库」,而非应用服务器。多JOIN且简单的SQL是不好优化的,而简略的SQL是比拟好优化的,并且我认为程序逻辑往往都要比SQL更容易保护

在我这两年在互联网公司中,关系型数据库在我的认知里,它就是作为一个反对事务的存储。如果咱们存储的数据对事务没有要求的,可能压根就不须要存储至关系型数据库中。

当初数据源可抉择的太多了,咱们能够把数据存储到Redis(内存数据库)、Elasticsearch(搜索引擎)、HBase(分布式、可伸缩的大数据存储)、HDFS(分布式文件系统)、clickhouse(OLAP存储系统)等等等

基于下面这些背景下,我的查问SQL就不会简单,那么Spring Data JPA不就很适宜我了么?

04、开发之外的数据库

去到有肯定规模的公司,都会有数据库相干的根底建设,上面提下常见的根底建设吧

、DDL和DML都须要走工单

生产环境的数据库实践都不能通过本人编写接口在程序中批改(高危动作),须要修数据或者建表都须要通过工单零碎审核(个别是数据库负责人+DBA)

比方你提交建表申请,DBA会看你的表设计是否正当(是否有加索引等等)

、DQL查问线上数据须要权限

咱们要查问线上的数据,个别都得申请库的权限,有了权限之后在公司内网特定的页面进行数据查问(咱们个别只须要查团队内的数据,所以其实也还好,其余团队的数据库权限是不凋谢的,要数据个别只能通过接口获取)

、程序上个别不直连数据库(会有代理层)

个别只有线下数据库能够通过ip直连,线上数据库都会通过代理层(代理层能够做很多货色,包含监控鉴权分库分表等等)

、齐备的监控告警

数据库作为一个很重要的存储之一(如果挂了是真的影响很大),会有齐备的监控和告警。比如说执行SQL失败的告警、执行慢SQL的告警等等,对数据库的各种指标进行实时监控

05、austin建表DDL

如果有提前预习的同学,应该就晓得在austin.sql下我放了两张表的DDL。为了让大家了解我在做什么,我来解释下这两张表的DDL具体是什么含意(为什么我要建这两张表)

message_template这张表开始解释吧,所有的字段我都增加了正文,应该还是比拟容易看得懂的。

:如果程序因为扩大导致数据库正文有落后,还是有必要更新下(造福前人)

咱们须要让所有的音讯都有一个「载体」,这个载体说白了就是模板,模板是austin零碎的基石(有了模板,能力做业务解决,能力溯源,能力数据统计,能力扩大出一整套的建设...)

上面聊下几个可能大家有疑难的几个字段吧:

  • audit_statusflow_id:模板在发送之前须要通过审核(这在发送音讯里十分重要,这会很大水平上能避免对音讯的误发(置信大家也能看到各大公司都有过发错音讯的报道)
  • msg_type音讯类型:分隔不同的音讯类型,能够在下发时让不同的类型走不同的通道进行实现音讯隔离(营销类的音讯即使堵住了,也不会影响到告诉类的音讯)
  • send_account发送账号:一个渠道内可能会有多个账号发送(比方,邮件渠道能够抉择不同的邮件组进行发送、短信渠道能够抉择不同的短信类型账号进行发送)
  • deduplication_timeis_ngiht_shield平台规定:作为发送类型的组件(平台),须要有通用的规定。而去重和夜间屏蔽下发这种就很适宜在平台内做
  • msg_conteng:这个字段是作为音讯内容发送的外围,不同的渠道对应下发的格局都不一样,我前面会间接将JSON存储进去。反对占位符的形式进行替换
  • ...

有可能后续还会扩大字段(毕竟在初期思考设计表的时候,不会尽全尽美)。这种作为模板或者了解为配置的表,从应用上就注定它不会有很大的数据量。

上面来看下sms_record表吧,其实这表能说的不多(就是要把短信发送的记录以及短信的回执存储进去)。它的作用一方面是能追踪到为何发送给某个用户的短信失败了,另一方面是将这些记录进行关联做对账应用。

06、总结

这篇文章其实想我聊的是:数据库是一个很重要的角色,如果它挂了会影响很大很大。但同时,咱们很多时候都是“轻量级”地去应用它(通过简略的SQL),它的存在很多时候是因它能很好地反对事务(数据强一致性)。

咱们最可能信赖的数据就是存储在数据库的,其余的存储咱们可能放心会丢、会多、会不实时等等(这是数据库比其余存储的最大的劣势)

我说得不对肯定,不要以我的为准,咱们能够在评论区聊