首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Java+MySQL开发规范

Mysql开发规范

严禁在sql script中使用SELECT * , 业务当中需要使用哪些字段, 就返回哪些字段.

统计行数时,使用 select count(*) from xxx

所有的SQL关键字以及系统函数都使用全大写的方式. 例如: SELECT, INSERT, UPDATE, CURRENT_TIMESTAMP(), ORDER BY, GROUP BY, INNER JOIN, LEFT JOIN.

多个表Join时, 必须指定别名, 参考如下的例子:

注意:应尽量减少表链接,同时注意驱动表的选择,索引等问题。

数据库,表,字段的编码使用utf8mb4

字段名命名可读性要强,常用字段比如手机号,邮箱要保持相同的命名。

InDate,EditDate建议取数据库时间NOW(3)

通常表中要有以下通用字段, id, status, system_status,in_user_id,in_user_name,in_date, edit_user_id, edit_user_name, edit_date

数据库字段尽量不为NULL

数据库字段不使用默认值。

主键,外键,常用于检索的日期字段加索引,只有少量状态值的字段不加索引

MySQL设计反例及相关经验总结

回顾过去一两年参与的项目中遇到的一些不好的设计:

字段长度过长,比如ProjectName varchar(500), 感觉真的有点不太合理,后来我专门去生产环境数据库中查询了一下最大长度只有131,所以根据这个情况,最大冗余255个字符就相对合理了。

字段名设计不合理:项目的地理位置经度,纬度被设计为LocationX, LocationY。呃,显然不太好,应该是经度longitude,纬度latitude。

数据库通用字段CommonStatus的值被定义为-999--已删除(逻辑删除),0--无效,1--有效。现在回过头来看,应该拆分为两个字段"系统状态"(SystemStatus TINY INT, 0--已删除,1--正常),数据状态(DataStatus TINYINT, 0--禁用,1--启用)

InDate,EditDate建议取数据库时间NOW(3)。有一些场景特别关注时间的,比如物联网云对云模式采集数据时,供应商数据上报时间会携带在消息体中,平台在接收到数据时会将消息扔到MQ中,MQ的订阅者在接收到消息时,会持久化。在这个场景中应该根据业务要求分别对待这些时间点。比如在数据持久化时建议使用MySQL系统时间NOW(3)。

在一些关系表设计中,建议使用具体唯一性的字段做为唯一索引(比如role_id, user_id)。比如system_role_user

SQL_CALC_FOUND_ROWS在数据量比较大的表上使用时,性能不稳定。建议还是使用count(*)语句来计算总行数。或者在一些可以不关注总行数的业务场景中,可以不计算,比如app上的滚动到底部加载下一页的场景。

在IN语句中不要有过多的值,比如限定不能有超过20个。超过了阈值的业务场景应该考虑换一种写法,比如使用临时表+连接的方式。

在join,where的条件中如果字段的类型(比如一个是字符串,一个是数字)或编码不一致(比如一个是utf8,一个是utf8mb4)时,可能会导致full table scan或full index scan。

要特别注意where语句中出现or, union等复杂子查询的场景。这种情况一般可以使用临时表+连接来优化性能。

尽量减少表连接,如果需要使用,那么需要特别关注相关连接字段,筛选条件,排序条件是否有索引,索引是否合理(比如考虑覆盖索引,减少filesort等等),驱动表选择是否合理。当连接比较多时,会导致代码难以理解,遇到问题时很容易无从下手。

在大表分页场景,应尽量减少大表连接,可以先从大表主键分页,取当前分页的数据,然后再回表取每一行的数据。比如

Java开发规范

所有Java Bean(DTO)必须实现Serializable,并生成serialVersionUID

记录详细的日志,比如重要的流程节点记录详细的有意义的warning log。又可以分为运维相关和业务相关。比如在写业务待办通知时,如果用户没有注册通道或者不允许推送,那么在写业务待办时就不会写推送通知。此时应该记录warning log, 以便于我们排查问题,关注业务动作过程。

mybatis中不使用mybatis.type-aliases-package, 在mapper中使用全类名

mybatis中使用resultMap,参数中指定更多的参数类型等信息,使用mybatis-generator来生成相关代码。

gitlab merge request: 我们使用gitlab的merge request来搞,每个人基于develop拉取最新的分支,每次提交代码前将develop(现在是新项目,就直接是develop, 以后是各个feature分支)合并到自己的分支,自己先将冲突解决掉,保证编译通过,冒烟测试通过,然后提交merge request, 由相关的人进行代码审核,审核通过后,会merge到develop。

业务方法命名要直观容易理解,同时方法参数只能出现主键类简单类型,比如soId, supplierSkuId, retrunId等,其它场景 必须使用DomainModel来定义,不能直接使用简单参数。可以针对每个场景定义不同的DomainModel, 比如同步摄像头可以定义为SyncCameraRequest,

一些性能,安全方面的总结

尽量减少取数据的数量: 取大量数据时,会耗费更多DB,redis, es等等磁盘,内存,CPU,网络等资源。

延迟加载数据:尽量只加载用户第一眼需要看的数据,其它数据由用户的操作行为驱动。

关键的高并发业务需要有压测,用数据来衡量系统容量,进而才能做好容量评估。

要有明确的监控,灾难恢复等运维兜底方案。

参考资料

MySQL 高性能表设计规范

MySQL数据库设计规范

mysql的SQL_CALC_FOUND_ROWS 使用 类似count(*) 使用性能更高

MySQL Documentation

一次慢查询暴露的隐蔽问题

==MySQL 索引及查询优化总结==

==Spring MVC/Boot 统一异常处理最佳实践==

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190114G17Y9500?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券