我的SQL坏习惯

SQL编程坏习惯

我很负责地说我是一名SQL专家 - 我的一个同事如是说当我为他/她写的一些逻辑伪代码就是他所期望的那样而且是可执行的SQL。·「注1」我完全有能力写出干净的可读性强的SQL-但是大多数其实不然。尽管我还有一些坏习惯体现在我的SQL中,后会无期下面是我的一些坏习惯,希望其他人不再犯同样的过失。

Order/Group by列号

当在有大量重复的查询语句中通过列号快速书写如某个东西你想order by。这里是一个简单轻量级的例子:

SELECT
  email,
  created_at
FROM 
  users
ORDER BY 2 DESC
LIMIT 5;
这个查询给我最近注册我的站点的5位用户。当然一旦我有了这个,我就可以 在上面添加一些数据,如他们的first name,我就可以发欢迎的email。我快速的修改查询:
SELECT
  email,
  first_name,
  created_at
FROM 
  users
ORDER BY 2 DESC
LIMIT 5;
现在我有5位已经按first name排序的注册用户了。当你只有1列要排序时是十分显而易见的,但是当你有GROUP BY 1, 2, 3, 4, 5, 6时这是十分的迷惑不清,而且这个确实出现在当前我已打开的标签中。

如果你确实想娱乐娱乐,可以我其他人分享像下面一样的查询:

SELECT
  email as "3",
  first_name "2",
  created_at "1"
FROM 
  users
ORDER BY "1", "3" DESC
LIMIT 5;

隐式联接(Implicit Joins)

我很少使用INNER JOIN语法,相反我只是简单的把两个表放到我的where语句中保证我有一个where条件。问题是有时我不能保证我有一个where条件,特别是当你要处理3个表时。

SELECT 
  email,
  product.name,
  product.price
FROM 
  users,
  orders,
  items
WHERE users.id = orders.user_id
  AND orders.id = items.order_id
相比这种情况,当处理5到6个表时更加不明确:
SELECT 
  email,
  product.name,
  product.price
FROM users
INNER JOIN orders on users.id = orders.user_id
INNER JOIN items on orders.id = items.order_id

缺少注释

和注释我的代码相比我注释我的SQL少之又少,但是它可以如此简单的完成。例如在我的查询语句中有这么一个:

SELECT convert_from(CAST(E'\\x' || array_to_string(ARRAY(
   SELECT 
     CASE 
       WHEN length(r.m[1]) = 1 
     THEN encode(convert_to(r.m[1], 'SQL_ASCII'), 'hex') 
     ELSE substring(r.m[1] from 2 for 2) 
     END
  FROM regexp_matches(url_here, '%[0-9a-f][0-9a-f]|.', 'gi') AS r(m)
), '') AS bytea), 'UTF8');
这个查询有它自身的问题因为没有文档解释它到底干什么,相反:
--- DECODES url ---
SELECT convert_from(CAST(E'\\x' || array_to_string(ARRAY(
   SELECT 
     CASE 
       WHEN length(r.m[1]) = 1 
     THEN encode(convert_to(r.m[1], 'SQL_ASCII'), 'hex') 
     ELSE substring(r.m[1] from 2 for 2) 
     END
  FROM regexp_matches(url_here, '%[0-9a-f][0-9a-f]|.', 'gi') AS r(m)
), '') AS bytea), 'UTF8');
注释在行内末尾一样可以。

大量人为生成的列表

大多数时间我在处理一些想过滤的由我手动或者自动生成的列表。一个常见例子就是过滤出staging/dev environments.我经常会手动搜索和裁剪列表,然后保存结果为后面的我即将进行的查询做准备。这会是相当费力的但是感觉值得的工作,缺点是结果可能像:

SELECT 
  foo
FROM 
  bar
WHERE 
  bar.id NOT IN (34723, 42735, 32321, 47205, 20375, 30261, 26194, 109371, 9313, 6351, 20184, 50273, 34735, 39854, 23954, 25323, 23405, 30528, 50182, 29340, 47659, ... and the list goes on)
SQL应该合理的包含这些逻辑。数据修改,硬编码在某些点上让你十分犯难,多努力一点来重复利用一些东西使之清晰明白。

其它

我相信这种坏习惯还相当多。我希望花几分钟时间和那些能指出其它坏习惯的人坐下来聊聊。我知道我的坏习惯至少是一些坏习惯,我还经常和别人交流。你呢?我喜欢听到这篇文章就是为他人而写,希望他们可以在开发中减少相同的坏习惯。如果你有其它坏习惯,请让我知道: craig.kerstiens@gmail.com

注1:这里是意译,主要说我很牛,而且他们都这么说。为后文他的一些SQL坏习惯做对比,即反面教材。

转载于:https://my.oschina.net/swuly302/blog/137855

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值