我们所有使用关系数据库的人都知道(或正在学习)SQL是不同的。获得期望的结果,并有效地这样做,涉及到一个乏味的过程,其部分特征是学习不熟悉的范例,并发现一些我们最熟悉的编程模式在这里不起作用。常见的反模式是什么?
当前回答
我见过太多人死死抓着IN(…),却完全忘记了EXISTS(存在)。有关一个好例子,请参见Symfony Propel ORM。
其他回答
使用无意义的表别名:
from employee t1,
department t2,
job t3,
...
使得阅读一个大的SQL语句比它需要的要困难得多
我只是把这个放在一起,基于一些SQL响应这里在SO。
认为触发器之于数据库就像事件处理程序之于OOP是一种严重的反模式。有一种看法是,任何旧的逻辑都可以放入触发器中,当一个事务(事件)在表上发生时被触发。
不正确的。最大的区别之一是触发器是同步的——而且是完全同步的,因为它们在集合操作上是同步的,而不是在行操作上。在OOP方面,正好相反——事件是实现异步事务的有效方法。
不必深入浅出:不使用准备好的语句。
我最喜欢的SQL反模式:
对非唯一列进行JOIN,并使用SELECT DISTINCT修剪结果。
创建连接多个表的视图,只是为了从一个表中选择少数列。
CREATE VIEW my_view AS
SELECT * FROM table1
JOIN table2 ON (...)
JOIN table3 ON (...);
SELECT col1, col2 FROM my_view WHERE col3 = 123;
使用@@IDENTITY代替SCOPE_IDENTITY()
引自以下回答:
@@IDENTITY returns the last identity value generated for any table in the current session, across all scopes. You need to be careful here, since it's across scopes. You could get a value from a trigger, instead of your current statement. SCOPE_IDENTITY returns the last identity value generated for any table in the current session and the current scope. Generally what you want to use. IDENT_CURRENT returns the last identity value generated for a specific table in any session and any scope. This lets you specify which table you want the value from, in case the two above aren't quite what you need (very rare). You could use this if you want to get the current IDENTITY value for a table that you have not inserted a record into.
推荐文章
- 选项(RECOMPILE)总是更快;为什么?
- 设置数据库从单用户模式到多用户
- oracle中的RANK()和DENSE_RANK()函数有什么区别?
- 的类型不能用作索引中的键列
- SQL逻辑运算符优先级:And和Or
- 如何检查一个表是否存在于给定的模式中
- 添加一个复合主键
- 如何在SQL Server Management Studio中查看查询历史
- 可以为公共表表达式创建嵌套WITH子句吗?
- 什么时候我需要在Oracle SQL中使用分号vs斜杠?
- SQL Server的NOW()?
- 在SQL中,count(列)和count(*)之间的区别是什么?
- 在SQL Server中截断(不是四舍五入)小数位
- 仅在Datetime列上按日期分组
- PostgreSQL通配符LIKE用于单词列表中的任何一个