我选择了MySQL和SpringData JPA
我是3y,一年CRUD
经验用十年的markdown
程序员常年被誉为优质八股文选手
今天想跟大家聊聊数据库层面上的事,austin项目继续更新(注:今天聊的数据库都特指关系型数据库)
01、数据库选择
之前发了一张我可能要在austin项目上引入哪些技术栈的图,好多人问我分布式配置中心为什么不选择Nacos,而是用Apollo。却没人问我为什么数据库选择MySQL。
说起来MySQL,在网上看到的各类Java教程,几乎都是使用MySQL作为数据库。日常在群里聊各种数据库上的问题,也差不多都是MySQL,只有个别的可能用PostgreSQL和Oracle或其他
就连我在面试的时候,我也没被面试官问过:“你的数据库为什么选择MySQL啊?这块技术选型是怎么样的”
看到这里,是不是觉得我有答案了?其实我也没有。写到一半的时候发现我也说不出啥比较好的理由...既然我不知道,于是我就去看看人家是怎么说的。
https://www.zhihu.com/question/21793412/answer/32127410
总结原因可能是:
- 前期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 性能。
喜欢用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),它的存在很多时候是因它能很好地支持事务(数据强一致性)。
我们最能够信任的数据就是存储在数据库的,其他的存储我们可能担心会丢、会多、会不实时等等(这是数据库比其他存储的最大的优势)
我说得不对一定,不要以我的为准,我们可以在评论区聊
欢迎关注我的微信公众号【Java3y】来聊聊Java面试,对线面试官系列持续更新中!
【对线面试官+从零编写Java项目】 持续高强度更新中!求star!!原创不易!!求三连!!
Gitee链接:https://gitee.com/austin
GitHub链接:https://github.com/austin
我选择了MySQL和SpringData JPA的更多相关文章
- 带你搭一个SpringBoot+SpringData JPA的环境
前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 不知道大家对SpringBoot和Spring Da ...
- SpringBoot整合SpringData JPA入门到入坟
首先创建一个SpringBoot项目,目录结构如下: 在pom.xml中添加jpa依赖,其它所需依赖自行添加 <dependency> <groupId>org.springf ...
- springdata jpa基本注解
Springdata jpa的基本注解 1:@Entity @Entity注解用在实体类声明语句前,说明该Java类为实体类,将映射到指定的数据库表. 2:@Table @Table注解用在当实体类与 ...
- Spring、SpringMVC、SpringData + JPA 整合详解
原创播客,如需转载请注明出处.原文地址:http://www.cnblogs.com/crawl/p/7759874.html ------------------------------------ ...
- 【极简版】SpringBoot+SpringData JPA 管理系统
前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 在上一篇中已经讲解了如何从零搭建一个SpringBo ...
- 6.4 SpringData JPA的使用
引言:该文档是参考尚硅谷的关于springboot教学视屏后整理而来.当然后面还加入了一些自己从网上收集整理而来的案例! 一.SpringData JPA初步使用 1. springdata简介 2. ...
- 一篇 SpringData+JPA 总结
概述 SpringData,Spring 的一个子项目,用于简化数据库访问,支持 NoSQL 和关系数据库存储 SpringData 项目所支持 NoSQL 存储 MongDB(文档数据库) Neo4 ...
- 第11章—使用对象关系映射持久化数据—SpringBoot+SpringData+Jpa进行查询修改数据库
SpringBoot+SpringData+Jpa进行查询修改数据库 JPA由EJB 3.0软件专家组开发,作为JSR-220实现的一部分.但它又不限于EJB 3.0,你可以在Web应用.甚至桌面应用 ...
- Springboot集成SpringData JPA
序 StringData JPA 是微服务框架下一款ORM框架,在微服务体系架构下,数据持久化框架,主要为SpringData JPA及Mybatis两种,这两者的具体比较,本文不做阐述,本文只简单阐 ...
随机推荐
- Markdown 语法粗学
Markdown 语法粗学 Typora下载 Typora官网 下拉点击右上角 选择下载即可 里面选择自己想要的系统下载即可 如果下载缓慢,推荐使用各自的下载工具或者使用软件管家等 亲测迅雷速度尚可 ...
- Excel里的格式会自动变成日期或会计专用吗?(Excel技巧集团)
Excel里的格式会自动变成日期或会计专用? 正常情况下当然不会了,可是最近却有很多很多同学问这样的问题,并把这个问题列成了Excel2007和2010的一个Bug,可是小妖同学却从来没遇到过这样的问 ...
- libevent源码学习(1):日志及错误处理
目录 错误处理函数 函数声明 __attribute__指令 函数定义 可变参数宏 _warn_helper函数 日志处理 event_log日志处理入口 日志处理回调函数指针log_fn 设置日志处 ...
- 电压-电流转换(一):4-20mA电流环
在仪表电路中,直流信号通常用作物理测量值的模拟表示,例如温度.压力.流量.重量和运动.最常见的是,直流电流信号优先于直流电压信号使用,因为在从电源(测量设备)到负载(指示器.记录仪或控制器)的整个串联 ...
- 创建Ubuntu server 服务器git项目
服务器端: mkdir project.git cd project.git git init --bare cd .. p.p1 { margin: 0; font: 11px Menlo; col ...
- Simple16 字符压缩
#define S16_NUMSIZE 16 #define S16_BITSSIZE 28 #define Simple16_Mask 0x7FFFFFFF extern int S16_NUM[] ...
- 【LeetCode】506. Relative Ranks 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 排序 argsort 堆 日期 题目地址:https ...
- 【LeetCode】322. Coin Change 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 动态规划 日期 题目地址:https://leetc ...
- Now冥想:崩溃服务和性能服务助力提升应用质量
想就像心灵的"健身房",当遇到失眠或情绪问题时,我们可以通过冥想,抚平情绪波澜,享受放松时刻.<Now冥想>正是一款专注冥想与心理健康的应用.它基于国际先进的正念冥想理 ...
- 从源码看全局异常处理器@ExceptionHandler&@ExceptionHandler的生效原理
1.开头在前 日常开发中,几乎我们的项目都会用到异常处理器,我们通常会定制属于自己的异常处理器,来处理项目中大大小小.各种各样的异常.配置异常处理器目前最常用的方式应该是使用@ControllerAd ...