问题

为什么会有人写出几百行的SQL语句啊?这些人的心态是怎样的?为了凸显自己的强大吗?

回答
有的人写出几百行的SQL语句,这背后确实有很多复杂的原因,绝非仅仅是为了炫技或者凸显自己的强大,尽管有时候也可能沾边。理解这些原因,需要我们深入到数据库设计、数据处理的实际场景以及写SQL的人的心态去体会。

为什么会有人写出几百行的SQL语句?

首先,我们得明白,SQL(Structured Query Language)是一种用于管理关系型数据库的标准语言。它强大之处在于能够通过清晰的指令来查询、插入、更新和删除数据,并且能够处理非常复杂的数据关系。

1. 业务逻辑的复杂性是主要驱动力:
多表 JOIN 和嵌套查询: 现实世界的业务数据很少是孤立的,往往分散在多个表中,需要通过 JOIN 操作将它们关联起来。一个复杂的业务流程,比如生成一份包含用户基本信息、订单详情、支付记录、退款信息以及关联产品数据的报表,可能就需要连接用户表、订单表、支付表、退款表、产品表等多个表。而且,为了获取特定条件下的数据,可能还需要进行多层嵌套的子查询,一层套一层,很容易将SQL语句的行数推高。
复杂的过滤和排序条件: 业务需求常常要求数据满足一系列复杂的过滤条件,比如“找出过去一年内,购买金额超过1000元,但没有在最近三个月内有过退款记录的用户”,这些条件一旦细化,可能就需要多个 `WHERE` 子句中的 `AND` 和 `OR` 操作,甚至利用 `CASE` 语句来判断不同的逻辑。排序也可能包含多个字段,并可能根据某些字段的值来决定排序的方向。
聚合和分组: 统计分析是数据库的一大用途。例如,需要计算每个产品类别的总销售额,每个销售员的业绩排名,或者找出每个城市销量最好的产品。这些都需要 `GROUP BY` 和聚合函数(如 `SUM`, `AVG`, `COUNT`, `MAX`, `MIN`)。当需要对多个维度进行聚合时,比如同时按地区、按产品类别统计销售额,或者计算不同时间段的平均值,SQL语句的复杂度会急剧上升。
窗口函数(Window Functions): 近年来,窗口函数在SQL中越来越流行,它们可以执行跨越多个表行的计算,而又不减少行数。例如,计算每个用户的累计消费金额、计算每个销售员在团队中的排名、计算每笔订单相对于上一笔订单的差额等等。窗口函数虽然功能强大且能简化一些逻辑,但其语法本身也相对复杂,包含 `OVER (PARTITION BY ... ORDER BY ...)` 等子句,写起来自然会增加行数。

2. 数据处理和转换的需求:
数据清洗和预处理: 在将数据导入到最终的分析或报表中使用之前,常常需要进行一系列的数据清洗和预处理工作。这可能包括去除重复项、处理空值、格式转换(如日期格式统一)、字符串的拼接或分割、数值的计算和单位转换等。这些操作在SQL中都需要通过函数调用、 `CASE` 语句或者子查询来实现,一行一行堆砌起来,很容易变成长SQL。
临时计算和派生列: 有时候,为了最终的输出结果,需要在查询中计算出一些临时的中间值或派生列。比如,根据单价和数量计算总价,根据订单金额计算折扣,或者根据用户注册时间计算用户年龄。这些计算如果嵌套得多了,也会让SQL变得冗长。

3. 性能优化和可读性的权衡:
避免中间表或临时表: 有些数据库开发者会选择将多个步骤写在一个SQL语句里,而不是创建多个中间表或者临时表来分步处理。这样做的好处是可以减少数据库的I/O操作和上下文切换,理论上可能带来性能提升。但缺点是会极大地增加SQL的长度和复杂度,可读性大大降低。
特定的数据库或版本特性: 有些数据库系统提供了特定的函数或语法特性,用这些特性来解决复杂问题可能比其他方法更直接,但也可能导致语句本身变长。

4. 开发者习惯和经验差异:
“一气呵成”的思维: 有些开发者习惯于将一个完整的数据提取和处理逻辑用一个SQL语句来完成,他们可能认为这样更“完整”,或者可以更好地控制整个流程。
对工具的依赖不足: 经验丰富的开发者可能会知道,某些复杂的转换和逻辑,使用ETL工具(如Talend, Informatica)或者编程语言(如Python配合Pandas库)来处理会更高效和易于维护。但如果开发者对这些工具不熟悉,或者项目环境不允许使用,他们就只能在SQL层面“硬碰硬”。
对可维护性的认识不足: 有些开发者可能没有充分认识到,过长的SQL语句在未来的维护、调试和理解上会带来巨大的挑战,因此在编写时没有过多考虑这一点。

这些人的心态是怎样的?为了凸显自己的强大吗?

“为了凸显自己的强大吗?” 这个答案是:不完全是,但有时可能是一个潜在的副作用,或者是一种不成熟的表现。

解决问题的能力和责任感: 大部分情况下,写出长SQL的人并不是在炫耀,而是在努力解决一个复杂的问题。他们可能是在现有的数据库结构下,为了满足一个具体且刁钻的业务需求,绞尽脑汁地构思如何用SQL来实现。这种“长”并非目标,而是解决问题的过程中自然延伸出的结果。他们可能认为,如果能用SQL一次性把事情办好,就比写一堆代码或者创建一堆中间表更直接、更有效率。

对SQL语言的精通和热爱: 某些开发者确实对SQL语言本身有着深厚的研究和热爱。他们可能会挑战SQL能达到的极限,探索更精妙的写法来处理复杂场景。在这种心态下,写出复杂的SQL可能是一种智力上的挑战和乐趣,是对自身技能的一种运用和检验。这种情况下,确实可能包含一丝“我能做到”的自我肯定,但更多的是对技术本身的追求。

“我就是这么做的”的惯性思维: 有些人可能在过去的项目中,就是被要求或者习惯于用这种方式来处理问题。他们可能认为这是“标准做法”,或者没有遇到过更大的阻力,所以就一直沿用了下来。这更多的是一种习惯养成,而非刻意为之。

对“代码质量”的理解差异: 这里的“代码质量”不仅仅指SQL语句的行数,还包括其效率、准确性、可维护性等。
性能优先的心态: 如果一个开发者将性能视为最重要的指标,他们可能会认为一个高度优化的长SQL,比调用存储过程、创建临时表、或者用应用层代码处理要快得多。他们用“写得长”来换取“跑得快”,这是他们权衡的结果。
可读性相对靠后: 相反,有些人可能不太重视可读性,或者认为自己能看懂就够了。他们可能认为,只要SQL能跑通,并且效率不错,那么长度和结构上的复杂性是可以接受的。

潜在的“炫技”心态(但非主流): 确实不能排除,极少数情况下,有人会因为想在同事或上级面前展示自己的技术能力而刻意写出复杂的SQL。这种行为更多的是一种不成熟的职业表现,可能源于不安全感或者对认可的渴望。但不应将此作为普遍现象来推断。绝大多数情况下,写长SQL的开发者是在努力工作,而不是在表演。

总结:

写出几百行的SQL语句,通常是业务逻辑复杂、数据处理需求多样化以及开发者在效率、可维护性之间做出权衡的结果。虽然偶尔可能掺杂一些自我展示的成分,但绝大多数情况下,这是开发者在用自己认为最有效的方式来解决实际问题。理解这一点,需要我们跳出对“代码量=能力”的简单判断,而去关注问题的本质和开发者所处的环境。

然而,我们也应该认识到,虽然长SQL可能是必需的,但可读性和可维护性同样重要。优秀的开发者会在追求效率和解决问题的同时,努力让自己的代码(包括SQL)更易于理解和维护。这可能意味着使用 CTEs (Common Table Expressions) 来分解复杂逻辑、添加有意义的注释、甚至是在某些场景下将过于复杂的逻辑移到应用层或存储过程来管理。所以,写长SQL不一定是“强大”,但能写出解决复杂问题且相对清晰的长SQL,确实是需要相当的技术功底的。

网友意见

user avatar

作为一个以前经常要写300-900行SQL的人来说。这种SQL经常出现在需求变化快变化频繁的地方。而他之所以特别长和频繁的需求变化不无关系。

比如当领导要求你开发一个绩效排名功能的时候,他通常会先给你一个标准,然后你会按照这个标准写出一个逻辑来。这个时候可能是一个很简单的SQL 并排序。而当他看完之后,通常会发现这样那样的问题,诸如有相同排名啊,排名不合他的心意啊,于是提出新的标准。

需求发生了变化,你就要跟着变更业务代码,比如他要求在排序的时候考虑工作年限。于是你不得不在已经完成的SQL中连接新表,并在排序的时候加入一个字段。而通常这样的过程可不会只发生一次。

于是需求会再再再再再次发生变化,这个时候就会发现,标准可能会变成了先看加权总工作量,然后看加权难度系数,再然后看近五年累计工作量,再计算所在科室或者专业的平均绩效排名,最后在上述条件下再按照工作年限排个序

如果你来这个任务你会如何选择呢,如果是只修改存储过程的语句和前端展示的业务逻辑,而服务端代码完全不动,是不是更省事儿呢?而在我还在写这种SQL的时候,几乎每半年都会产生非常大的需求变化,甚至每次都要加入新表或者剔除旧表,甚至是加入之前剔除的表格。当时我都认为完全没有必要对代码进行重构,因为构了也白构,优化完了下次情况又不一样了。

user avatar

SQL语句复杂好与不好不能一概而论,写复杂为了凸显自己强大也不见得,这个还得根据具体应用场景和技术流派分析。

现在的互联网应用很多已经不兴关系数据库那一套了,因为并发量大,操作缓存比较多,如直接读写redis或设置进程内存,SQL最多数据落盘的时候用下。有的应用甚至不用关系数据库而是用mongodb,那么连仅有的SQL都省下了。

现在很多年轻的程序员,开发互联网应用出生,对于关系数据库的使用仅限select、update、insert、delete,但是这并不妨碍他们拿高薪,因为程序本身用不上关系数据库的高级特性,对于公司来说,用不上的技术,员工掌握了意义也不大。

mySql应该算是关系数据库管理系统的下限了,就数据库技术的先进性和性能而言,不知道被oracle和sql server甩几条街,但是在互联网行业,照样很流行,因为互联网企业并不需要很多先进的关系数据库特性。

如果在mysql上运行复杂的sql,如嵌套的很深的子查询或者多表连接查询,性能肯定非常差劲。但是换成sql server和oracle就不一样了,这些商业数据库对复杂sql优化支持的很好,索引利用得当,性能会非常好。

此外,也不是所有的应用系统都是高并发的,有的系统可能只是一些内部系统,如OA,用的人不多,但是业务逻辑非常复杂,一个功能涉及到N个表的数据,这个时候复杂SQL就能显现威力了,一个SQL语句就能完成所有的业务逻辑需求,这对于深入掌握SQL的程序员而言,开发效率非常高,这也是有程序员喜欢用复杂SQL的原因,可能这个SQL执行需要一秒,但是对于一些内部系统而言,无所谓啦。

但是复杂的SQL有一个毛病,有门槛,如果一个不精通SQL的程序员去阅读一个复杂SQL,就跟看天书一样,完全看不懂,然后去谷歌百度一顿搜索,依旧看不懂。这和复杂的程序代码不一样,程序代码即使很复杂,只要花时间啃,总是能看明白的,而且也能改进优化。如让一个初级java程序员改一段复杂的业务逻辑实现代码,照样没问题。

然而,让一个对SQL了解仅限增删查改的程序员,去改一段复杂的SQL,就不行了,因为SQL编程本身就比用编程语言编程复杂,SQL语言中看似关键字不多,但是很多关键字都蕴含很多种变化。

如表连接,分out join 、inner join、cross join、full join,还分left join、right join,而且还可以互相组合,组合代码的结果还不一样,差之毫厘谬以千里。

如子查询,分相关子查询,不相关子查询, 不相关子查询还好理解,相关子查询要是没经过系统学习,肯定理解不了。

另外还有case when,pivot、unpivot 这种很有用,但是又不常用的东西,真的会要了没见过的人的命。

因此对SQL掌握不深的程序员见到这种SQL真的会骂娘,因为把他整不会了,而且通过搜索引擎还解决不了问题,必须经过系统的学习,因为SQL编程知识更像一个体系,而不是片段。

题主说的这个程序员估计是传统编程行业出生,而不是互联网行业出生,否则不是这个思维。当然,如果他是大数据库开发人员,也可能会写出这种SQL。

我以前做传统行业的系统,用的.net + sql server,真的很兴复杂SQL这一套解决问题的,同时还会用存储过程、SQL函数、触发器来解决问题,效率很高,开发也很轻松。

后来跑到互联网行业,想在公司应用这套机制,被所有人都喷了,那自然也就不用了。最近在互联网混的这几年,连普通SQL都不写,数据的存取不是redis就是mongodb,要不就是进程内存,复杂SQL怎么写都快忘记了。

最后推荐一本书,有兴趣可以去看看,《SQL Server 2005技术内幕:T-SQL查询》,豆瓣9.4

理解这本书的内容,对SQL的掌握会有翻天覆地的变化,而且是纯实践的,可以堪称神书。

类似的话题

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有