黑马程序员技术交流社区
标题: Java 开发者写 SQL 时常犯的 10 个错误-----后5个 [打印本页]
作者: hy2014051202 时间: 2017-7-24 18:51
标题: Java 开发者写 SQL 时常犯的 10 个错误-----后5个
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 去。它说了如下查询给不出结果:
http://sqlfiddle.com/#!12/d41d8/1303
SELECT 1
WHERE 1 IN (NULL)
UNION ALL
SELECT 2
WHERE NOT(1 IN (NULL))
解决方案:
当涉及到可为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这个页面上有解析。
http://use-the-index-luke.com/sql/partial-results/fetch-next-page
解决方案:
不管干什么都可以使用行值表达式。它们会让你的SQL语句更加简洁高效。
9、不定义足够的限制条件(constraints)
我又要再次引用Tom Kyte 和 Use The Index, Luke 了。对你的元数据使用限制条件不能更赞了。首先,限制条件可以帮你防止数据质变,光这一点就很有用。但对我来说更重要的是,限制条件可以帮助数据库进行SQL语句转换,数据库可以决定。
Tom Kyte
http://blog.jooq.org/2011/11/25/how-schema-meta-data-impacts-oracle-query-transformations/
Use The Index, Luke
http://use-the-index-luke.com/sql/where-clause/null/not-null-constraint
哪些值是等价的
哪些子句是冗余的
哪些子句是无效的(例如,会返回空值的语句)
有些开发者可能认为限制条件会导致(数据库)变慢。但相反,除非你插入大量的数据,对于大型操作是你可以禁用限制条件,或用一个无限制条件的临时“载入表”,线下再把数据转移到真实的表中。
解决方案:
尽可能定义足够多的限制条件(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语句。
作者: 623586742 时间: 2017-7-25 23:46
不好意思,看不懂
作者: hy2014051202 时间: 2017-7-26 19:00


作者: wangyupeng123 时间: 2017-7-26 20:13
顶起……
作者: hy2014051202 时间: 2017-7-27 19:04
谢谢
作者: 番茄炒鸡蛋 时间: 2018-5-1 07:45
学习一下!
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |