Mysql数据库表字段设计优化(状态列)

本文涉及的产品
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS AI 助手,专业版
简介: 初始状态码(java int 32 long 64),int 可以表示31种(除去0000),long可以表示63种(除去0000),当然不可能将0000赋值给初始状态,一般来讲,选择int还是long是根据具体业务需求来决定的。

Mysql数据库表字段设计优化(状态列)


一、传统用户状态设置


   传统的数据库表中,涉及到状态的字段时,通常都会第一反应就是将其设置为0和1来表示。比如需求是,设计一张表来检查用户状态(绑定邮箱,绑定手机,实名认证,是否已经开通VIP),我以前会这样设计Java类。


UserInfo


@Getter
@Setter
public class UserInfo extends baseDomain{
  private boolean realAuth;
  private boolean bindPhone;
  private boolean bindEmail;
  private boolean vip;
}


如果是用0和1来表示,咋看起来挺合理的,但是仔细想想,是否真的能够满足我们的需求?(也不符合我们作为完美主义者的追求)


二、使用二进制来表示状态


   我们使用二进制来表示状态看看效果。首先给每一个状态指定分配一个二进制,如


boolean realAuth  0001;
boolean bindPhonge 0010;
boolean vip 1000;
boolean bindEmail 0100;


那还有一个问题,就是在数据库中,使用int类型还是long类型?

诚然,初始状态码(java int 32 long 64),int 可以表示31种(除去0000),long可以表示63种(除去0000),当然不可能将0000赋值给初始状态,一般来讲,选择int还是long是根据具体业务需求来决定的。


   这里顺带提一下,为什么Java中的BitSet使用long数组做内部存储,而不使用int数组或者byte数组?


JDK选择long数组作为BitSet的内部存储结构是出于性能的考虑,因为BitSet提供and和or这种操作,需要对两个BitSet中的所有bit位做and或者or,实现的时候需要遍历所有的数组元素。


使用long能够使得循环的次数降到最低,所以Java选择使用long数组作为BitSet的内部存储结构。


从数据在栈上的存储来说,使用long和byte基本是没有什么差别的,除了编译器强制地址对齐的时候,使用byte最多会浪费7个字节(强制按照8的倍数做地址对其),另外从内存读数组元素的时候,也是没有什么区别的,因为汇编指令有对不同长度数据的mov指令。所以说,JDK选择使用long数组作为BitSet的内部存储结构的根本原因就是在and和or的时候减少循环次数,提高性能


   既然使用二进制表示状态的改变情况,如何进行运算的,又是如何知道通过二进制来获取状态?来试试状态改变时,二进制的运算是怎么样的。


   首先,假设用户已经绑定手机号码(响应国家要求,大多数网站注册时都已经需要绑定手机),绑定手机之后的状态码为:0010,这时用户申请开通了vip,


0010 || 1000  = 1010


只需要判断标志位是否为1即可,所以我们可以得到一个约定:


① 结合当前状态码添加一个状态码:当前状态码 || 要添加的状态码


② 判断当前用户是否拥有某种状态:当前状态码 || 要判断的状态码(如果等于0则说明没有,如果>0则有)


Eg:


  demo: 1010 & 0010 得到 0010 > 0


        判断是否绑定邮箱:


    1010 & 0100 得到 0000


③ 给当前用户去除某种状态(例如用户取消了VIP):当前状态码 ^ 要移除的状态码(相同为0,不同为1)


Eg:


   移除邮箱


1010 ^ 1000 得到 0010


三、使用二进制方式表示状态码的利弊权衡


   通过上述的例子,我们可以使用一个属性值表示多个状态。非常经典的页很常见的Linux系统中,使用的正是状态码,这里就不展开细讲了,有兴趣的朋友可以移步这里查看


https://blog.csdn.net/qq_36221862/article/details/56012469


   但坏处也是非常明显的,即有上限,查询复杂(SQL语句中也需要使用 || ^ & 来判断),例如,查询系统所有的vip会员,无法使用一条查询语句(只能使用判断状态码的方式)。还有一个很麻烦的情况就是,只要数据库中的某一列参与了运算,该列上添加的索引(记录的是列的原始值)就会失效。


   这里提供几种解决方案:


   ① 把经常参与查询的条件单独列成条件(列)


   ② 给列添加索引的时候注意,哪些列适合进行索引(区分度不高的列不适合,比如一个列是性别(只有男或者女),那不适合做索引,因为只能区分出一半的人)。


   ③ 在组合查询中,将运算放置在过滤条件最后


   ④ 使用全文检索(solr || Lucene)


以上只是个人在学习过程中的一些小总结,如有不当之处,还望海涵,希望前辈们多多指教。

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
目录
相关文章
|
4月前
|
存储 人工智能 NoSQL
AI大模型应用实践 八:如何通过RAG数据库实现大模型的私有化定制与优化
RAG技术通过融合外部知识库与大模型,实现知识动态更新与私有化定制,解决大模型知识固化、幻觉及数据安全难题。本文详解RAG原理、数据库选型(向量库、图库、知识图谱、混合架构)及应用场景,助力企业高效构建安全、可解释的智能系统。
|
8月前
|
关系型数据库 MySQL 数据库连接
Django数据库配置避坑指南:从初始化到生产环境的实战优化
本文介绍了Django数据库配置与初始化实战,涵盖MySQL等主流数据库的配置方法及常见问题处理。内容包括数据库连接设置、驱动安装、配置检查、数据表生成、初始数据导入导出,并提供真实项目部署场景的操作步骤与示例代码,适用于开发、测试及生产环境搭建。
400 1
|
8月前
|
SQL 缓存 关系型数据库
MySQL 慢查询是怎样优化的
本文深入解析了MySQL查询速度变慢的原因及优化策略,涵盖查询缓存、执行流程、SQL优化、执行计划分析(如EXPLAIN)、查询状态查看等内容,帮助开发者快速定位并解决慢查询问题。
349 0
|
4月前
|
SQL 存储 监控
SQL日志优化策略:提升数据库日志记录效率
通过以上方法结合起来运行调整方案, 可以显著地提升SQL环境下面向各种搜索引擎服务平台所需要满足标准条件下之数据库登记作业流程综合表现; 同时还能确保系统稳健运行并满越用户体验预期目标.
312 6
|
5月前
|
缓存 Java 应用服务中间件
Spring Boot配置优化:Tomcat+数据库+缓存+日志,全场景教程
本文详解Spring Boot十大核心配置优化技巧,涵盖Tomcat连接池、数据库连接池、Jackson时区、日志管理、缓存策略、异步线程池等关键配置,结合代码示例与通俗解释,助你轻松掌握高并发场景下的性能调优方法,适用于实际项目落地。
932 5
|
SQL 关系型数据库 MySQL
MySQL进阶突击系列(07) 她气鼓鼓递来一条SQL | 怎么看执行计划、SQL怎么优化?
在日常研发工作当中,系统性能优化,从大的方面来看主要涉及基础平台优化、业务系统性能优化、数据库优化。面对数据库优化,除了DBA在集群性能、服务器调优需要投入精力,我们研发需要负责业务SQL执行优化。当业务数据量达到一定规模后,SQL执行效率可能就会出现瓶颈,影响系统业务响应。掌握如何判断SQL执行慢、以及如何分析SQL执行计划、优化SQL的技能,在工作中解决SQL性能问题显得非常关键。
|
6月前
|
缓存 关系型数据库 MySQL
降低MySQL高CPU使用率的优化策略。
通过上述方法不断地迭代改进,在实际操作中需要根据具体场景做出相对合理判断。每一步改进都需谨慎评估其变动可能导致其他方面问题,在做任何变动前建议先在测试环境验证其效果后再部署到生产环境中去。
279 6
|
7月前
|
机器学习/深度学习 SQL 运维
数据库出问题还靠猜?教你一招用机器学习优化运维,稳得一批!
数据库出问题还靠猜?教你一招用机器学习优化运维,稳得一批!
256 4
|
7月前
|
存储 SQL 关系型数据库
MySQL 核心知识与索引优化全解析
本文系统梳理了 MySQL 的核心知识与索引优化策略。在基础概念部分,阐述了 char 与 varchar 在存储方式和性能上的差异,以及事务的 ACID 特性、并发事务问题及对应的隔离级别(MySQL 默认 REPEATABLE READ)。 索引基础部分,详解了 InnoDB 默认的 B+tree 索引结构(多路平衡树、叶子节点存数据、双向链表支持区间查询),区分了聚簇索引(数据与索引共存,唯一)和二级索引(数据与索引分离,多个),解释了回表查询的概念及优化方法,并分析了 B+tree 作为索引结构的优势(树高低、效率稳、支持区间查询)。 索引优化部分,列出了索引创建的六大原则
181 2

推荐镜像

更多