共计 3994 个字符,预计需要花费 10 分钟才能阅读完成。
明天想跟大家聊聊数据库层面上的事
注:明天聊的数据库都特指关系型数据库
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 表
然而,咱们在理论中生产环境中 很有可能 是不设计这种关联表,而是间接把相干字段 冗余 在一张表里。这样在查问的时候,就能间接通过一张表查到对应的信息了,不必进行 多层关联
如果按下面的构造进行查问:比方我要查到某一篇文章的作者根本信息,那我此时的动作是:
- 关联
author_content 表
查到文章的authorId
- 通过
authorId
去author 表
查到作者的根本信息
如果我把 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_status
和flow_id
:模板在发送之前须要通过 审核(这在发送音讯里十分重要,这会很大水平上能避免对音讯的误发(置信大家也能看到各大公司都有过发错音讯的报道)msg_type
音讯类型:分隔不同的音讯类型,能够在下发时让 不同的类型走不同的通道 进行实现音讯隔离(营销类的音讯即使堵住了,也不会影响到告诉类的音讯)send_account
发送账号:一个渠道内可能会有多个账号发送(比方,邮件渠道能够抉择不同的邮件组进行发送、短信渠道能够抉择不同的短信类型账号进行发送)deduplication_time
和is_ngiht_shield
平台规定:作为发送类型的组件 (平台),须要有 通用 的规定。而去重和夜间屏蔽下发这种就很适宜在平台内做msg_conteng
:这个字段是作为音讯内容发送的 外围 ,不同的渠道对应下发的格局都不一样,我前面会间接将 JSON 存储进去。反对 占位符 的形式进行替换- …
有可能后续还会扩大字段(毕竟在初期思考设计表的时候,不会尽全尽美)。这种作为模板或者了解为配置的表,从应用上就注定它不会有很大的数据量。
上面来看下 sms_record
表吧,其实这表能说的不多(就是要把短信发送的记录以及短信的回执存储进去)。它的作用一方面是能追踪到为何发送给某个用户的短信失败了,另一方面是将这些记录进行关联做对账应用。
06、总结
这篇文章其实想我聊的是:数据库是一个很重要的角色,如果它挂了会影响很大很大。但同时,咱们很多时候都是“轻量级 ”地去应用它(通过简略的 SQL),它的存在很多时候是因 它能很好地反对事务(数据强一致性)。
咱们最可能信赖的数据就是存储在数据库的,其余的存储咱们可能放心会丢、会多、会不实时等等(这是数据库比其余存储的最大的劣势)
我说得不对肯定,不要以我的为准,咱们能够在评论区聊