Java开发者写SQL时常犯的10个错误
作者:网络转载 发布时间:[ 2015/3/10 11:17:28 ] 推荐标签:Java 软件开发 数据库
6、认为 NOT (A IN (X, Y)) 和 IN (X, Y) 的布尔值相反
对于NULLs,这是一个举足轻重的细节!让我们看看 A IN (X, Y) 真正意思吧:
A IN (X, Y)
is the same as A = ANY (X, Y)
is the same as A = X OR A = Y
When at the same time, NOT (A IN (X, Y)) really means:
同样的,NOT (A IN (X, Y))的真正意思:
NOT (A IN (X, Y))
is the same as A NOT IN (X, Y)
is the same as A != ANY (X, Y)
is the same as A != X AND A != Y
看起来和之前说的布尔值相反一样?其实不是。如果X或Y中任何一个为NULL,NOT IN 条件产生的结果将是UNKNOWN,但是IN条件可能依然会返回一个布尔值。
或者换种说话,当 A IN (X, Y) 结果为TRUE或FALSE时,NOT(A IN (X, Y)) 结果为依然UNKNOWN而不是FALSE或TRUE。注意了,如果IN条件的右边是一个子查询,结果依旧。
不信?你自己看SQL Fiddle 去。它说了如下查询给不出结果:
SELECT 1
WHERE 1 IN (NULL)
UNION ALL
SELECT 2
WHERE NOT(1 IN (NULL))
更多细节可以参考我的上一篇博客,上面写了在同区域内不兼容的一些SQL方言。
解决方案:
当涉及到可为NULL的列时,注意NOT IN条件。
7、认为NOT (A IS NULL)和A IS NOT NULL是一样的
没错,我们记得处理NULL值的时候,SQL实现了三值逻辑。这是我们能用NULL条件来检测NULL值的原因。对么?没错。
但在NULL条件容易遗漏的情况下。要意识到下面这两个条件仅仅在行值表达式(row value expressions)为1的时候才相等:
NOT (A IS NULL)
is not the same as A IS NOT NULL
如果A是一个大于1的行值表达式(row value expressions),正确的表将按照如下方式转换:
如果A的所有值为NUll,A IS NULL为TRUE
如果A的所有值为NUll,NOT(A IS NULL) 为FALSE
如果A的所有值都不是NUll,A IS NOT NULL 为TRUE
如果A的所有值都不是NUll,NOT(A IS NOT NULL) 为FALSE
在我的上一篇博客可以了解到更多细节。
解决方案:
当使用行值表达式(row value expressions)时,要注意NULL条件不一定能达到预期的效果。
8、不用行值表达式
行值表达式是SQL一个很棒的特性。SQL是一个以表格为中心的语言,表格又是以行为中心。通过创建能在同等级或行类型进行比较的点对点行模型,行值表达式让你能更容易的描述复杂的判定条件。一个简单的例子是,同时请求客户的姓名
SELECT c.address
FROM customer c,
WHERE (c.first_name, c.last_name) = (?, ?)
可以看出,将每行的谓词左边和与之对应的右边比较这个语法而言,行值表达式的语法更加简洁。特别是在有许多独立条件通过AND连接的时候特别有效。行值表达式允许你将相互联系的条件放在一起。对于有外键的JOIN表达式来说,它更有用:
SELECT c.first_name, c.last_name, a.street
FROM customer c
JOIN address a
ON (c.id, c.tenant_id) = (a.id, a.tenant_id)
不幸的是,并不是所有数据库都支持行值表达式。但SQL标准已经在1992对行值表达式进行了定义,如果你使用他们,像Oracle或Postgres这些的复杂数据库可以使用它们计算出更好的执行计划。在Use The Index, Luke这个页面上有解析。
解决方案:
不管干什么都可以使用行值表达式。它们会让你的SQL语句更加简洁高效。
9、不定义足够的限制条件(constraints)
我又要再次引用Tom Kyte 和 Use The Index, Luke 了。对你的元数据使用限制条件不能更赞了。首先,限制条件可以帮你防止数据质变,光这一点很有用。但对我来说更重要的是,限制条件可以帮助数据库进行SQL语句转换,数据库可以决定。
哪些值是等价的
哪些子句是冗余的
哪些子句是无效的(例如,会返回空值的语句)
有些开发者可能认为限制条件会导致(数据库)变慢。但相反,除非你插入大量的数据,对于大型操作是你可以禁用限制条件,或用一个无限制条件的临时“载入表”,线下再把数据转移到真实的表中。
解决方案:
尽可能定义足够多的限制条件(constraints)。它们将帮你更好的执行数据库请求。
10、认为50ms是一个快的查询速度
NoSQL的炒作依然在继续,许多公司认为它们像Twitter或Facebook一样需要更快、扩展性更好的解决方案,想脱离ACID和关系模型横向扩展。有些可能会成功(比如Twitter或Facebook),而其他的也许会走入误区
对于那些仍被迫(或坚持)使用关系型数据 库的公司,请不要自欺欺人的认为:“现在的关系型数据库很慢,其实它们是被天花乱坠的宣传弄快的”。实际上,它们真的很快,解析20Kb查询文档,计算 2000行执行计划,如此庞大的执行,所需时间小于1ms,如果你和数据管理员(DBA)继续优化调整数据库,能得到大限度的运行。
它们会变慢的原因有两种:一是你的应用滥用流行的ORM;二是ORM无法针对你复杂的查询逻辑产生快的SQL语句。遇到这种情况,你要考虑选择像 JDBC、jOOQ 或MyBatis这样的更贴近SQL核心,能更好的控制你的SQL语句的API。
因此,不要认为查询速度50ms是很快或者可以接受的。完全不是!如果你程序运行时间是这样的,请检查你的执行计划。这种潜在危险可能会在你执行更复杂的上下文或数据中爆发。
总结
SQL很有趣,同时在各种各样的方面也很微妙。正如我的关于10个错误的博客所展示的。跋山涉水也要掌握SQL是一件值得做的事。数据是你有价值的资产。带着尊敬的心态对待你的数据才能写出更好的SQL语句。
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系SPASVO小编(021-61079698-8054),我们将立即处理,马上删除。
相关推荐
Java性能测试有哪些不为众人所知的原则?Java设计模式??装饰者模式谈谈Java中遍历Map的几种方法Java Web入门必知你需要理解的Java反射机制知识总结编写更好的Java单元测试的7个技巧编程常用的几种时间戳转换(java .net 数据库)适合Java开发者学习的Python入门教程Java webdriver如何获取浏览器新窗口中的元素?Java重写与重载(区别与用途)Java变量的分类与初始化JavaScript有这几种测试分类Java有哪四个核心技术?给 Java开发者的10个大数据工具和框架Java中几个常用设计模式汇总java生态圈常用技术框架、开源中间件,系统架构及经典案例等
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11热门文章
常见的移动App Bug??崩溃的测试用例设计如何用Jmeter做压力测试QC使用说明APP压力测试入门教程移动app测试中的主要问题jenkins+testng+ant+webdriver持续集成测试使用JMeter进行HTTP负载测试Selenium 2.0 WebDriver 使用指南