为什么不爱SQL?

Tra*_*vis 114 sql frameworks

我最近听说过SQL是一种糟糕的语言,似乎太阳下的每个框架都预先打包了一个数据库抽象层.

根据我的经验,SQL通常是管理数据输入和输出的更简单,更通用,更方便程序的方式.我使用的每个抽象层似乎都是一种显着有限的方法,没有真正的好处.

是什么让SQL如此糟糕,为什么数据库抽象层有价值?

Ste*_*ger 125

这在一定程度上是主观的.所以这是我的意见:

SQL具有伪自然语言风格.发明人认为他们可以像英语一样创建语言,并且数据库查询将非常简单.一个可怕的错误.除了琐碎的情况外,SQL很难理解.

SQL是声明性的.你不能告诉数据库如何应该做的东西,你想要的结果正是.如果您不必关心性能,这将是完美且非常强大的.所以你最终写了SQL - 读取执行计划 - 改写SQL试图影响执行计划,你想知道为什么不能自己编写执行计划.

声明性语言的另一个问题是一些问题更容易以命令式方式解决.因此,您要么使用其他语言编写(您需要标准SQL,可能需要数据访问层),要么使用特定于供应商的语言扩展,例如编写存储过程等.这样做你可能会发现你使用的是你见过的最糟糕的语言之一 - 因为它从未被设计成用作命令式语言.

SQL 很老了.SQL已经标准化,但为时已晚,许多供应商已经开发了语言扩展.所以SQL最终出现在几十种方言中.这就是应用程序不可移植的原因,也是拥有数据库抽象层的一个原因.

但这是事实 - 没有可行的替代方案.所以我们都将在未来几年内使用SQL.

  • "只要陈述你想要的东西 - 我们尽快交付".这种声明性方法很棒,而且它实际上是现代的(想想LINQ).有时你需要调整速度,而SQL的过程替代方案可能会有用.但是为了简单起见,我仍然大部分时间都在使用声明性SQL. (31认同)
  • 我完全同意.IT人员对非程序性工具非常着迷.如果你只是告诉电脑你想要什么,它会不会那么容易,它会弄清楚如何做到这一点!是的,如果计算机真的足够聪明,那么.但事实并非如此.如果我能告诉我的车"把我带到奶奶家",我会喜欢它,它会把我带到那里.但事实并非如此,所以我不会放开方向盘并假装这样可行.也许有一天,技术会存在,或者这可能是一个不可能实现的梦想.但它今天不存在.(继续 ...) (16认同)
  • 德勤.你的答案完美地描述了我早期对SQL的挫败感.我写了很多程序代码,因为我不相信SQL来生成有效的执行计划.随着我越来越熟悉SQL,我发现它实际上非常擅长优化,并且正确编写的SQL通常比我的过程代码运行得更快. (12认同)
  • @Jay和其他SQL怀疑者.根据我的经验,问题是要有效地使用SQL,你需要能够在集合方面进行思考而不是在程序上思考 - 这正是大多数程序员被教导思考的方式.有效地使用SQL并不是那么难,并且在任何有能力的编码人员都可以使用(就像任何阅读SO的人一样!)但是有必要努力跳到基于集合逻辑的思考,并且大部分时间人们都不愿意打扰(我正在修改一个程序,原始编码器使用游标完成所有操作,正是因为这个原因) (5认同)
  • MarkJ:我记得我重新排序了WHERE子句来优化oracle中的查询.他们从底部到顶部解决了......太可怕了. (4认同)
  • 我有相同的经验,确切知道一个好的执行计划是什么,数据库生成一个糟糕的,然后我必须修改查询,试图欺骗它生成正确的计划! (3认同)
  • 有多少次你真的不得不调整SQL?在大型企业IT环境中工作的两年时间里,我不得不调整SQL(使用查询提示)ONCE!在大多数情况下,计算机确实为您找到了解决方案并且相当好. (3认同)
  • "我记得我重新排序了WHERE子句来优化oracle中的查询." 在后来的评论中:"我认为它是版本8".Oracle发布了第8版[**1999年**](http://news.cnet.com/2100-1001-222355.html).从那时起,查询优化器已经走了很长的路.您是否曾经在过去5年发布的成熟RDBMS平台上进行过如此愚蠢的优化? (2认同)
  • @Jay和其他人:如果你经常发现自己说"愚蠢的优化者!" 那么我建议你仔细看看它可用的资源(统计数据,SARGability,实例配置),因为这不是**常态.覆盖优化器应该是一种特殊的行为!如果没有,你(和/或你的DBA)做错了什么.:) (2认同)

Mig*_*ura 58

除了所说的一切之外,技术并不一定要使抽象层变得有价值.

如果您正在执行一个非常简单的脚本或应用程序,您可以在任何您喜欢的代码中混合使用SQL调用.但是,如果您正在执行复杂的系统,则在单独的模块中隔离数据库调用是一种很好的做法,因此它会隔离您的SQL代码.它提高了代码的可读性,可维护性和可测试性.它允许您快速调整系统以适应数据库模型的变化,而不会破坏所有高级别的东西等.

SQL很棒.它上面的抽象层使它更大!

  • 非常外交!(说实话,开机!) (6认同)
  • 麻烦是抽象倒置.关系数据库中的SQL是基于集合的声明性环境.它比命令式编程具有更高的抽象级别,面向对象或没有. (2认同)
  • 也许是这样,史蒂文,但就应用而言,它执行低级功能(即使它以极高的水平方式执行).无论你在数据库级别做了什么疯狂的转换,在一天结束时它都是一个美化的吸气剂和设定者.或者您可以以相反的方式看待它,因为它与应用程序混合在一起太高,必须隔离并单独考虑.无论如何,将SQL保留在主应用程序代码之外在可读性和重构方面具有非常明显的好处. (2认同)

Joo*_*kka 53

抽象层的一个要点是,SQL实现往往或多或少彼此不兼容,因为标准略有模糊,而且因为大多数供应商都在那里添加了自己的(非标准)附加组件.也就是说,为MySQL数据库编写的SQL可能与Oracle数据库的工作方式不太相似 - 即使它"应该".

不过,我同意SQL比大多数抽象层更好.这不是SQL的错,它被用于它不是为它设计的东西.

  • 我不明白SQL方言的不兼容性如何成为对抗SQL的巨大"点".这就像说C是垃圾,因为你不能只在不同的Linux发行版中编译+运行相同的源代码.如果,并且它是一个大的IF,你的公司决定转换数据库供应商,这是一个罕见的大事件,有更多的移动部分,而不仅仅是重写一些SQL. (19认同)
  • @Jeff:在C中,常见任务是标准的一部分.在SQL中,如果不进入供应商特定的SQL,就不可能对结果集进行分页. (8认同)
  • 这不是针对SQL的一点,它是抽象层的一个重点.就像,你不能只在任何地方编译+运行相同的C代码,这是*更多平台无关紧要的语言的一点*.但它并没有使SQL或C"废话":无论如何,抽象层运行在更深层的顶部. (7认同)
  • 哦,关于切换数据库供应商的稀缺性:你在说什么?公司转换操作系统的稀缺性是否会使跨平台解决方案变得无关紧要?您并不总是事先知道您的产品将会运行什么,因此最好是采用更通用的解决方案. (4认同)
  • @Joonas:我想我的意思是说SQL语言不是问题 - 问题是什么让SQL变得如此可怕,而我最初的反应就像你的那样,是不是.但我想说,容纳不同的方言并不是ORM的重点 - 即使我们只有一种标准语言,我们也会拥有它们 - 我认为我们需要一种方法来将规范化数据解析为OO模型. (3认同)

Ste*_*wig 36

SQL从几个来源变得糟糕:

  • 对命令语言不熟悉的程序员.
  • 顾问必须每天处理许多不兼容的基于SQL的产品
  • 非关系数据库供应商试图打破市场上关系数据库供应商的束缚
  • 像Chris Date这样的关系数据库专家认为SQL的当前实现是不够的

如果您坚持使用一个DBMS产品,那么我绝对同意SQL DB比竞争对手更通用,质量更高,至少在您达到模型内在的可扩展性障碍之前.但是你真的想写下一个Twitter,还是只是想让一些会计数据保持整齐有序?

对SQL的批评通常是批评RDBMS的标准.RDBMSes似乎不理解的是,他们很好地解决了一大类计算问题,并且他们在这里使我们的生活更轻松,而不是更难.

如果他们认真批评SQL本身,他们就会像Tutorial D和Dataphor那样支持.

  • 关于程序员除了命令式语言之外什么都不熟悉的第一点.在接下来的几年里,看看函数式编程的复兴是否/如何对此产生任何影响都会很有趣.目前有很多关于Haskell,F#和Scala等语言的炒作使得开发人员的工作效率更高.程序员的这种"数学"思维非常类似于SQL预先假设的关系代数和元组关系演算的知识.也许会有一个基于本机SQL集的思想及时复苏! (7认同)

Tre*_*ins 22

这不是那么可怕.当一种新的"范式"出现时,这个行业的一个不幸的趋势是废弃以前可靠的技术.在一天结束时,这些框架很可能使用SQL与数据库进行通信,那么它怎么会这么糟糕呢?也就是说,拥有"标准"抽象层意味着开发人员可以专注于应用程序代码而不是SQL代码.如果没有这样的标准层,每次开发系统时都可能会编写一个轻量级的层,这是一种浪费精力的方法.


Mar*_*iss 16

SQL用于管理和查询基于SET的数据.它经常被用来做更多,边缘情况有时会导致沮丧.

SQL的实际使用可能会受到基础数据库设计的影响,SQL可能不是问题,但设计可能 - 当您丢弃与错误设计相关的遗留代码时,更改会更具隐蔽性且成本更高(没有人喜欢回去"修复"那些"正常工作"并达到目标的东西

木匠可以用锤子砸钉子,用锯子锯木材,用平面刨光板.可以使用锤子和飞机"锯",但是它很令人沮丧.


Nik*_*y R 11

我不会说这太可怕了.它不适合某些任务.例如:你不能用SQL编写好的过程代码.我曾被迫使用SQL进行集合操作.我整整一个周末都想到了这一点.

SQL是为关系代数设计的 - 这就是它应该被使用的地方.

  • -1,错误,这正是重点,SQL设计为基于集合,这是它的力量.在程序方面的思考意味着你在思考错误. (5认同)
  • 不幸的是,将一些简单的过程代码粘贴到存储过程中非常诱人.它工作正常.UNTIL有人需要维护它/添加一些例外等等...... (2认同)

Qua*_*noi 9

我最近听说过SQL是一种糟糕的语言,似乎太阳下的每个框架都预先打包了一个数据库抽象层.

请注意,这些图层只是将自己的内容转换为SQL.对于大多数数据库供应商SQL来说,这是与引擎通信的唯一方式.

根据我的经验,SQL通常是管理数据输入和输出的更简单,更通用,更方便程序的方式.我使用的每个抽象层似乎都是一种显着有限的方法,没有真正的好处.

...我刚才描述的原因.

数据库层不添加任何内容,它们只限制您.他们使查询更加简单,但从未提高效率.

根据定义,数据库层中没有任何内容SQL.

是什么让人SQL如此可怕,为什么数据库抽象层有价值?

SQL 是一种很好的语言,然而,它需要一些大脑扭曲才能使用它.

从理论上讲,它SQL是声明性的,即您声明要获得的内容,并且引擎以尽可能最快的方式提供它.

实际上,有很多方法可以形成正确的查询(即返回正确结果的查询).

优化器能够使用一些预定义的算法构建乐高城堡(是的,它们是多个),但它们无法制作新的算法.它仍然需要SQL开发人员来帮助他们.

但是,有些人希望优化器能够产生"可能的最佳计划",而不是"在给定的SQL引擎实现的情况下,这个查询可用的最佳计划".

众所周知,当计算机程序无法满足人们的期望时,会受到指责,而不是期望.

但是,在大多数情况下,重新构建查询可以确实产生最佳计划.然而,有些任务是不可能的,随着SQL这些案例的新的和不断增长的改进越来越少.

这将是很好,但是,如果厂商提供喜欢的功能,一些低级别的访问"获得索引范围","由获得行rowid等",如C编译器让你嵌入汇编权到语言.

我最近在我的博客上写了一篇关于此的文章:


Bri*_*Kay 7

我是一个巨大的ORM倡导者,我仍然相信SQL非常有用,虽然它可以用它来做可怕的事情(就像其他任何事情一样)..

我将SQL视为一种超级高效的语言,没有代码重用或可维护性/重构作为优先级.

因此闪电快速处理是首要任务.这是可以接受的.你必须要注意权衡,这对我来说是相当可观的.

从美学的角度来看,作为一种语言,我觉得它缺少一些东西,因为它没有OO概念等等 - 这对我来说感觉就像是非常古老的学校程序代码.但它是做某些事情的最快方式,而且这是一个强大的利基!


Der*_*sed 7

我会说框架中包含的数据库抽象层是一件好事,因为它解决了两个非常重要的问题:

  1. 它使代码保持不同. 通过将SQL放入另一个层(通常非常薄,并且应该只执行查询和切换结果的基础知识(以标准化方式)),您可以使应用程序免于SQL的混乱.这与Web开发人员(应该)将CSS和Javascript放在单独的文件中的原因相同.如果可以避免,请不要混淆语言.

  2. 许多程序员在使用SQL时都很苛刻. 无论出于何种原因,大量开发人员(特别是Web开发人员)在使用SQL或RDBMSes时似乎非常非常糟糕.他们将数据库(和扩展的SQL)视为他们必须经历的肮脏的中间人来获取数据.这导致了极其糟糕的数据库,没有索引,表格以可疑的方式堆叠在表格之上,以及写得非常糟糕的查询.或者更糟糕的是,他们试图过于笼统(专家系统,任何人?),并且无法以任何有意义的方式合理地关联数据.

不幸的是,有时某人试图解决他们使用的问题和工具的方式,无论是由于无知,固执还是其他特征,都是彼此直接对立的,并且好运试图让他们相信这一点.因此,除了仅仅是一个好的做法之外,我认为数据库抽象层是一种安全网,因为它不仅使SQL不受开发人员的影响,而且使得他们的代码更容易重构,因为所有查询都在一个地方.


Jef*_*nal 6

SQL非常适合某些类型的任务,尤其是操作和检索数据.

但是,SQL缺少(或仅部分实现)几个用于管理变更和复杂性的重要工具:

  • 封装:SQL的封装机制很粗糙.编写SQL代码时,您必须了解有关数据实现的所有信息.这限制了您可以实现的抽象量.

  • 多态性:如果要在不同的表上执行相同的操作,则必须编写两次代码.(可以通过富有想象力地使用视图来缓解这种情况.)

  • 可见性控制:没有标准的SQL机制可以将代码段彼此隐藏或将它们分组为逻辑单元,因此每个表,过程等都可以从其他每个表中访问,即使它是不合需要的.

  • 模块化版本控制

最后,在SQL中手动编写CRUD操作(并编写代码以将其连接到其他应用程序的其余部分)是重复且容易出错的.

现代抽象层提供了所有这些功能,并允许我们在隐藏破坏性重复实现细节的同时使用最有效的SQL.它提供了有助于克服对象 - 关系阻抗不匹配的工具,这使得面向对象的软件开发中的数据访问变得复杂.


小智 5

SQL基于集合论,而现在大多数高级语言都是面向对象的.对象程序员通常喜欢在对象中思考,并且必须进行心理转换以使用基于Set的工具来存储他们的对象.一般情况下,它是更自然的(对于OO程序员)到刚刚晋级的代码在自己选择的语言,这样做,而不必编写SQL查询和调用数据库来实现object.save或object.delete在应用程序代码同样的结果.

当然,有时候对于复杂的东西,SQL更容易使用,效率更高,所以掌握这两种技术都很好.


Tho*_*mas 5

IMO,我看到人们使用SQL的问题与关系设计和SQL语言本身无关.它与数据层建模的学科有关,这在很多方面与建模业务层或接口根本不同.与使用数据库的多个应用程序的数据层相比,表示层建模中的错误通常更容易纠正.这些问题与在SOA设计中对服务层建模时遇到的问题相同,您必须考虑服务的当前使用者以及输入和输出合同.

SQL旨在与关系数据库模型进行交互.还有其他数据模型已经存在了一段时间,但无论使用何种理论模型,都存在正确设计数据层的规则,因此,开发人员通常对SQL的困难通常与强制非关系的尝试有关.数据模型到关系数据库产品上.