当前位置: 首页 > news >正文

SQL查询优化——数据结构设计

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

本文部分内容会涉及mysql,可能在其他数据库中并不适用。本章节只针对数据库结构设计做讨论,查询优化的其他内容待续。

数据库设计及使用是WEB开发程序员必备的一项基础技能,在大数据量和高并发场景,合理的数据结构及SQL查询优化对项目来说都会显得格外重要。大部分有经验的程序员都能了解到,程序的瓶颈往往不在程序本身,而在数据访问层。造成数据访问效率低下的原因有很多,如何解决这些问题,直接影响到应用的稳定性、健壮性。以下列举几个常见的问题:

  • 数据库锁表,查询阻塞
  • 高并发场景下,链接数量瓶颈
  • 查询效率低下,程序长时间无法退出
  • 写入性能低下,造成读写竞争激烈

以上只是列出了数据库使用过程中比较常见的问题,出现这些问题的常见原因列举如下:

  • 数据结构设计不合理
  • 索引设计糟糕
  • 程序维护数据链接不合理
  • 程序员太懒惰,数据库做了不擅长的工作
  • 数据冗余
  • SQL太渣

本节只对数据结构设计不合理进行讨论,后续章节会继续讨论其他内容。

一直觉得作为一个中级以上水平的程序员,查询优化是一项必备的基础技能。良好的数据结构设计,直接影响到后期软件的性能、健壮性、可维护性、可扩展性。见过很多因为数据结构设计不合理而造成软件最终难以扩展,难以维护的场景。要避免这些问题,我们就要掌握良好的数据结构设计能力。

怎样的数据结构才是合理的?这并没有一个完美通用的解决方案,要考虑具体的应用场景。但有一些准则,使我们应该尝试去遵守的。列举如下:

  1. 根据业务查询场景,考虑数据结构分布
  2. 如果没有业务主键,应建立ID自增主键
  3. 保证使用较小的数据类型,避免空间浪费
  4. 合理控制表的字段数量,必要时分表存储
  5. 添加字段注释

针对以上几点,分别详述如下:

1、根据业务场景,考虑数据结构分布

业务场景,决定了你要存储什么样的数据,但它不会决定你要如何存储这些数据。你可以简单的将这些信息存储到一张表里,例如user表。但当我们需要更多的信息,例如用户的附属属性(学校,住址等),如果全部塞到一张表里,对于小数据量的数据库不会有太大问题,但当遇到大数据量的场景时,查询就有可能变的缓慢。分表会是一个更好的解决方案,根据不同的业务场景,将这些信息分为两类,存储在不同的表里,是更加合理的解决方案。

这里要说的其实是,不要为了方便把所有的东西都塞到一张表里,虽然这样会让你的程序编写起来容易很多,但是会造成更多的问题。例如有些人会把1:N的关系存储到一张表里,这样就会带来数据冗余,坏处有很多,例如:针对N的写改删查都会变得很复杂;表体积变大、字段增多,造成查询缓慢;其他表链表查询时速度缓慢等等。

2、如果没有业务主键,应建立ID自增主键

主键是一条记录的唯一标志,没有主键在很多时候我们无法得心应手的操作数据。可能在某些场景下,我们确实没有设置主键的必要,但无论你是否主动设置主键,数据库都会有一个主键(如果你没有主动设置,数据库默认会有一个ROW_ID列,而这一列是你看不到的)。主键在连表、查询等方面业务提供很大帮助,所以无论如何,建立一个主键是很必要的

3、保证较小的数据类型,避免空间浪费

较小的数据类型意味着较小的存储代价,且数据库能够更高效的利用缓存空间。存储引擎都会采用不同的方式对索引或者数据缓存在内容中,较小的数据类型意味着在有限的内容空间中,你能够存储更多有价值的数据。对于可变长度的varchar类型,如果我们设置的是20长度,但实际占用的只有10个长度,在载入内存时,占用的空间依旧是20而不是10。所以对于可变长度类型,合理的长度更为重要。

4、合理控制表的字段数量,必要时分表存储

字段数量过多如果不是因为业务需且数据结构设计合理,大多会产生以下几个问题:

  • 数据冗余
  • 索引过多
  • 表体积大

这里要提醒避免不必要的数据冗余,针对数据冗余的讨论我们暂且放在后面。

因为字段数据量多,往往查询场景也会非常复杂多变,所以索引也就跟着变多了。索引多会直接影响到表的写入性能,这个性能的损耗是非常大的,可能是数以十倍计算的时间损耗。在写入频繁的场景,有可能会出现写入瓶颈。由于写入而影响读取性能的问题也很多。

表体积大意味着数据库在读取数据的时候需要扫描更多更大的数据块,载入内存做缓存时也不能充分利用缓存带来的效果。表大小对于表的性能也是由为重要的。

分表是解决字段过多的一个解决方案,数据库分表后,程序可能会改动比较大,但我们应该追求合理完美的软件设计,摒弃糟粕。分表后使用链表查询,或者在程序中做两次查询。有些人可能会觉得连表,性能一定很差,其实不然。连表意味着我们在同一个SQL中,可以使用两个索引,但是单表查询我们只能使用一个索引。如果索引设计合理,在大多数场景下(应该是大数据量场景),连表查询会比单表查询性能更高,甚至高出太多。曾经有过这样的场景,优化分表后画面变得没好多了。

5、添加字段注释

这里只是为了提示规范化数据库设计。

转载于:https://my.oschina.net/yonghan/blog/793523

相关文章:

  • $(function(){})与(function($){....})(jQuery)的区别
  • zabbix监控多tomcat实例
  • 小小小游戏
  • ApacheHttpServer出现启动报错:the requested operation has failed解决办法
  • Inodes 清理
  • vmware虚拟化无法迁移虚拟机
  • Docker for windows10 配置阿里云镜像
  • Hadoop集群搭建步骤
  • 网站开发流程以及HTML5简介(九)
  • windows 下的tcping 小插件
  • 当数据库字段是图片URL时怎样在单元格中显示图片
  • 快速删除段落间多余的空行
  • 编写grains自定义脚本
  • html分页插件
  • ArcGIS for android访问天地图
  • 【347天】每日项目总结系列085(2018.01.18)
  • 【vuex入门系列02】mutation接收单个参数和多个参数
  • 【跃迁之路】【733天】程序员高效学习方法论探索系列(实验阶段490-2019.2.23)...
  • android百种动画侧滑库、步骤视图、TextView效果、社交、搜房、K线图等源码
  • Android优雅地处理按钮重复点击
  • CAP理论的例子讲解
  • docker容器内的网络抓包
  • ES6之路之模块详解
  • HTML-表单
  • JavaScript设计模式与开发实践系列之策略模式
  • js学习笔记
  • JS专题之继承
  • Kibana配置logstash,报表一体化
  • macOS 中 shell 创建文件夹及文件并 VS Code 打开
  • niucms就是以城市为分割单位,在上面 小区/乡村/同城论坛+58+团购
  • overflow: hidden IE7无效
  • Shadow DOM 内部构造及如何构建独立组件
  • v-if和v-for连用出现的问题
  • 多线程事务回滚
  • 复习Javascript专题(四):js中的深浅拷贝
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 技术发展面试
  • 简单基于spring的redis配置(单机和集群模式)
  • 前端面试之CSS3新特性
  • 区块链共识机制优缺点对比都是什么
  • 如何抓住下一波零售风口?看RPA玩转零售自动化
  • 深度学习在携程攻略社区的应用
  • 什么软件可以剪辑音乐?
  • 详解移动APP与web APP的区别
  • 想写好前端,先练好内功
  • 由插件封装引出的一丢丢思考
  • 源码之下无秘密 ── 做最好的 Netty 源码分析教程
  • 3月7日云栖精选夜读 | RSA 2019安全大会:企业资产管理成行业新风向标,云上安全占绝对优势 ...
  • 关于Android全面屏虚拟导航栏的适配总结
  • # 日期待t_最值得等的SUV奥迪Q9:空间比MPV还大,或搭4.0T,香
  • ## 临床数据 两两比较 加显著性boxplot加显著性
  • ### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException
  • #NOIP 2014# day.1 T3 飞扬的小鸟 bird
  • #考研#计算机文化知识1(局域网及网络互联)
  • (3)STL算法之搜索