面向集合的思想
SQL是为查询和管理关系型数据库中的数据而专门设计的一种标准语言。我们通常认为的关系型是说的数据库中表与表的关系,这个理解是有问题的,这里的关系其实是数学术语上的关系。为什么这么说?因为关系型数据库是以关系模型为基础,而关系模型是以集合论和谓词逻辑两大数学理论为依据的。集合论中,关系是集合的一种表示。在关系模型中,关系是相关信息的一个集合,反映到数据库中就是一张表。我们知道集合是不关心顺序的。表作为一个集合,它本身并没有顺序的概念。在很久之前有人问过,我按顺序插入id=1,2,3的记录,为什么查处来时和插入的顺序不一致。很多程序员都有这样的认为,就是从表选取记录时,记录是按插入顺序或主键的大小顺序返回的。在SQL评审中也经常遇到不带ORDERBY 的LIMIT语句。这么写实际上是有问题的,不带ORDER BY子句的查询只表示从集合中查询数据,返回的结果是不确定的,之所以结果看起来对的,是因为MySQL访问数据的方式和你的需求恰巧一致了,表上索引或数据的变化都可能会影响到你的结果。因此要牢记不要为表中的行假定任何特定的顺序,确定需要按某个顺序取数时显式的加上ORDER BY。
很多程序员都是先有面向过程和面向对象的对象的编程经验后开始SQL编程的,这往往限制了对SQL问题的思考。SQL和传统编程语言最大的区别是它以关系模型和集合论为背景。在SQL编程中最能体现面向过程和面向集合区别的就是对游标的使用,面向过程的编程同样体现在使用中对子查询、派生表、以及临时表的过多依赖。许多程序员的编程经验是把一个任务细分成许多小任务,而后按一定的顺序来实现它们或先把需要的数据存储在各个临时表或先包含在派生表里再做关联处理。但如果按这种方式处理SQL编程,可能只会得到平庸的结果。这类实现往往是代码很长,很难维护,欠缺灵活性,而最大问题是由于相对固化的处理逻辑限制了优化器的优化空间,大多数情况下这类面向过程的实现在性能上都远不如面向集合的实现。编写高效的SQL需要我们跳出原有面向过程的思维方式,换一种思维方式去思考问题。可以总结为:解决SQL问题时要关注的是获取“什么”,而不是“如何”去获取。SQL是一门注重思想而非技巧的语言。