IN 操作符
IN 操作符允许您在 WHERE 子句中查找多个值。
SQL IN 语法
SELECT column_name(s)
FROM table_name
WHERE column_name IN (value1,value2,...);
IN 操作符实例
(使用Northwind样本数据库) SELECT * FROM Customers WHERE City IN ('Paris','London');
MongoDB 语法
db.collection.find( { type: { $in: [ 'food', 'snacks' ] } } )
EXISTS
NOT EXISTS,exists的用法跟in不一样,一般都需要和子表进行关联,而且关联时,需要用索引
,这样就可以加快速度
exists是用来判断是否存在的,当exists(查询)中的查询存在结果时则返回真,否则返回假。not exists则相反。
in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。一直以来认为exists比in效率高的说法是不准确的。
如果查询的两个表大小相当,那么用in和exists差别不大。
如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in:
例如:表A(小表),表B(大表)
select * from A where cc in (select cc from B)效率低,用到了A表上cc列的索引;
select * from A where exists(select cc from B where cc=A.cc)效率高,用到了B表上cc列的索引。
select * from B where cc in (select cc from A)效率高,用到了B表上cc列的索引;
select * from B where exists(select cc from A where cc=B.cc)效率低,用到了A表上cc列的索引。
not in 和not exists如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;
而not extsts 的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快。
SQL LIKE 操作符
LIKE 操作符用于在 WHERE 子句中搜索列中的指定模式。
SQL LIKE 语法
SELECT column_name(s)
FROM table_name
WHERE column_name [NOT] LIKE pattern;
SQL 通配符
在 SQL 中,通配符与 SQL LIKE 操作符一起使用。
SQL 通配符用于搜索表中的数据。
在 SQL 中,可使用一下通配符:
通配符 描述
通配符 | 描述 |
---|---|
% | 替代 0 个或多个字符 |
_ | 替代一个字符 |
[charlist] | 字符列中的任何单一字符 |
[^charlist]or[!charlist] | 不在字符列中的 |
MongoDB 语法
db.users.find( { user_id: /bc/ } )
等价于
SELECT *
FROM users
WHERE user_id like "%bc%"
MongoDB Java驱动中查询采用Pattern正则作为条件
1.调用解释器
在Unix机器上,Python的解释器通常安装于/ usr/local/bin/python3.4 ,在这个目录/usr/local/ bin你也可以通过输入命令来启动它:
python3.4
当然,那只是一个安装选项,如果要改变请联系您安装Python的用户或系统管理员。(例如,在/ usr /local/python是一种很常见的选择。)
在Windows机器上,Python的安装通常是放在 C:\ Python34,你可以在运行安装程序进行更改。你可以把这个目录添加到环境变量path中,你可以键入以下命令进入命令提示符在DOS窗口:
set path=%path%;C:\python34
可以通过输入值(在Unix上键入文件结束的字符为Control-D
,在Windows上按Ctrl-Z
)让解释器以零退出状态。如果这样做不起作用,你可以通过键入以下命令:退出 quit()
退出解释器 。
解释器的行编辑功能通常并不很复杂。在Unix上,安装的解释器可能已启用了GNU readline库支持,它增加了更多的精巧的交互编辑和历史记录功能。也许是最快的检查命令行编辑器是否支持输入控制,就是在第一个Python提示符按Ctrl-P。如果发出哔哔声,你可以使用命令行编辑功能,你可以查阅交互输入和历史替换,或者按^ P
,查看命令行编辑行是否存在,你只能用退格键,从当前行删除字符。
解释器的操作有些像Unix Shell:当与标准输入连接到一个tty设备时,它会以交互方式读取并执行命令,当以一个文件名 参数或以文件做为标准输入时,它读取文件并执行文件里的脚本。
启动解释器的第二个方法是 python -c command [arg] ...
,这个执行语句的命令,等同于Shell的 -c
选项。因为Python语句通常会把对空格或其他字符做特殊对待,如果命令行用引号通常使用单引号。
一些非常有用的Python模块通常用脚本编写。这些可以通过 python -m module [arg] ...
命令调用,执行源文件作为模板,前提是你在命令行上拼写对了文件全名。
脚本文件被使用时,交互模式是很有用的。在脚本之前,可以通过 passing -i 。
1 参数传递
在解释器中,脚本名和附加参数后都变成了一个字符串列表,在sys
模式下分配给 argv
的变量。您可以通过执行访问这个list 通过导入import sys
。这个list的长度至少是1;在没有脚本没有参数时,sys.argv[0]
是一个空字符串。当脚本名称被给定为 “ - ” (意思是标准输入),sys.argv中[0]
被设置为-
。当 -c
命令执行时,sys.argv中[0]被设置为'-c' 。当 -m
模块被使用时,sys.argv中[0] 被设置为本地模块的全名。在 -c
命令或-m
模块后面的可选项,不会被Python解释器的选项处理,留在sys.argv
中的命令或模块来处理。
2 交互模式
当从一个tty读取命令,解释器是处在交互模式下的。在这种模式下,它会提示一个符号输入下一个命令,通常是三个大于号(>>>);继续的部分用三个点(...)提示表示。在书写第一行时解释器会打印欢迎信息、版本号还有版权声明:
$ python3.4
Python 3.4 (default, Mar 16 2014, 09:25:04)
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
当输入连续行时,继续行...是必须的。你可以看下面的if语句的列子:
>>> the_world_is_flat = True
>>> if the_world_is_flat :
... print("Be careful not to fall off!")
...
Be careful not to fall off!
2.解释器及其环境
1 错误处理
当错误发生时,解释器打印一个错误信息和栈跟踪信息。在交互模式下,它返回主提示符,如果从文件输入进来,它会在打印栈跟踪器后以非零状态退出。(异常在try-except语句下处理了,不算错误)有些错误是无条件致命的,造成出口以非零退出,这可能由于内部矛盾和某些情况下运行内存溢出造成。所有的错误信息都写入标准错误流;其他的普通输出写入标准输出流。
输入中断符(通常是Control-C
或DEL
),从主要或次要提示取消输入并返回到主提示符。[2] 输入一个中断,执行时会引发的 KeyboardInterrupt异常,它可以由一个try语句处理。
2 可执行的Python脚本
在BSD'ish Unix系统中,Python脚本可直接执行,就像shell脚本,如下:
#! /usr/bin/env python3.4
(假设解释器在用户的PATH上)在脚本开始之前,给该文件设置为可执行模式。#!
必须是文件的前两个字符。在某些平台上,第一行必须以Unix风格的行结束符(\n
)结尾,不是Windows结束符(\r\n
)的行结束。需要注意的是哈希,或pound,字符,'#',是用来作为Python中的注释开始的。
该脚本可以得到一个可执行的模式,或许可使用 chmod 命令:
$ chmod +x myscript.py
在Windows系统中,没有“可执行模式”的概念。Python的安装程序python.exe会自动关联.py
文件,所以可以作为一个脚本双击运行它。使用.pyw
扩展也可以,在这种情况下,通常显示的控制台窗口被限制。
3 源代码编码方式
默认情况下,Python源文件的编码方式为UTF-8。在这种编码方式,世界上多少语音都可以同时使用在字符串、标识符和注释中, 虽然标准库只使用ASCII字符的标识符,但任何可移植的代码应该会遵循一个约定。为了正确显示所有的字符,你的编辑器必须认识到,该文件是UTF-8,并且必须使用支持文件中所有字符的字体。
它也可以指定源文件的编码不同。为了做到这一点,#!之后用一个特殊的注释行来定义源文件编码:
# -*- coding: encoding -*-
根据这个声明,一切在源文件中的代码,将被视为具有具体的编码,而不是默认为UTF-8。可能的编码列表可以在Python库参考手册中找到,可以参考codecs一节。
例如,如果您选择的编辑器不支持UTF-8编码的文件,并坚持使用一些其他的编码 Windows 1252,你可以这样写:
# -*- coding: cp-1252 -*-
仍然要在源文件中使用Windows-1252字符设置。那么必须在文件的第一或第二行内设置特殊编码注释。
4 交互式启动文件
当您使用Python的交互方式,在解释器启动时它常常有一些很方便的命令。你可以通过设置一个名为PYTHONSTARTUP的环境变量做到这一点,让包含你的启动的文件名称。这是类似.profile
文件在Unix Shell中。
该文件只会在交互Session中读取,而不是使用Python从脚本中读取命令,也不 是使用/dev/tty作为外部命令源(否则就像一个交互式会话)。它执行在交互式命令相同的命名空间,所以它定义的对象还有导入的都不能在交互的Session外。您还可以更改提示sys.ps1和sys.ps2指令在这个文件中。
如果你想读从对比当前目录的额外地方启动文件,你可以在全局启动文件使用这样的代码: if os.path.isfile('.pythonrc.py'): exec(open('.pythonrc.py').read())
。如果你想要使用的启动文件在一个脚本中,你必须在脚本中显式地声明:
import os
filename = os.environ.get('PYTHONSTARTUP')
if filename and os.path.isfile(filename):
exec(open(filename).read())
5 自定义模块
Python提供了两个钩子地方,让你实现自定义:sitecustomize和 usercustomize。看看它是如何工作的,你需要先找到你的 site-packages目录的位置。启动Python和运行此代码:
>>> import site
>>> site.getusersitepackages()
'/home/user/.local/lib/python3.2/site-packages'
现在你可以在该目录中创建一个文件名 为usercustomize.py,然后把你想要的任何东西写在里面。他会影响到Python的每次调用,除非在开始的时候采用 -s的选项来禁用自动导入。
sitecustomize的采用同样的方式,但通常是由计算机管理员在全局的site-packages目录创建,且在usercustomize导入之前。可以从site获取更多的信息。
脚注
[1] 在Unix上,Python 3.x的解释器在默认情况下不会以Python命名安装,因此它不会和同时安装Python 2.x的可执行文件相冲突。 [2] 使用GNU Readline软件包的一个问题可能会阻止这一点。
何谓重构
对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提交其可理解性,降低其修改成本。
- 重构的目的是软件更容易理解和修改;
- 重构不会改变软件可观察的行为。
两顶帽子比喻
- 添加新功能 不修改既有代码,只管添加新功能,并通过测试
- 重构 不添加功能,只管改进程序结构
为何重构
重构改进软件设计
- 改进的重要方向就是消除重复代码。
重构使软件更容易理解
准确说出我所要的
利用重构来协助我理解不熟悉的代码
随着代码渐趋简洁,发现可以看到一些以前看不到的设计层面的东西。
重构帮助找到BUG
我不是个伟大的程序员,只是个有着一些优秀习惯的好程序员。
重构提高编程速度
何时重构
几乎任何情况下都反对专门拨出时间重构。重构应该随时随地。不应该为重构而重构,你之所以重构,是因为你想做别的什么事,而重构可以帮助你把那些事做好。
三次法则
事不过三,三则重构
添加功能时重构
最常见的重构时机就是我想给软件添加新特性的时候。
往往是为了帮助我理解需要修改的代码。
代码结构清晰,我就可以从中理解更多的东西。
代码的设计无法帮助我轻松添加我所需要的特性。
重构是一个快速流畅的过程
修补错误时重构
调试过程中运用重构,多半是为了代码更具可读性。
复审代码时重构
重构可以帮组我复审别人的代码。
程序难以相与的原因:
- 难以阅读的程序,难以修改;
- 逻辑重复的程序,难以修改;
- 添加新行为时需要修改已有代码的程序,难以修改;
- 带复杂条件逻辑的程序,难以修改。
希望的程序:
- 容易阅读;
- 所有逻辑都只在唯一地点指定;
- 新的改动不会危及现有行为;
- 尽可能简单表达条件逻辑。
技术复审是减少错误,提高开发速度的一条重要途径。
“计算机科学是一门科学:它相信所有问题都可以通过增加一个间接层来解决。 Dennis DeBruler”
但是它是一把双刃剑。
间接层的某些价值:
- 允许逻辑共享。 比如说一个子函数在两个不同的地点被调用,或超类中的某个函数被所有子类共享。
- 分开解释意图和实现。 你可以选择每个类和函数的名字,这给了你一个解释自己意图的机会。类或者函数内部则解释实现这个意图的做法。如果类和函数内部又以更小单元的意图来编写,你所写的代码就可以描述其结构中的大部分重要信息。
- 隔离变化。 很可能我在两个不同的地点使用同一个对象,其中一个地点我想改变对象行为,但如果修改了它,我就要冒同时修改两处的风险。为此,我做出一个子类,并在需要修改处引用这个子类。现在,我可以修改这个子类而不必承担无意中影响另一处的风险。
- 封装条件逻辑。 对象有一种奇妙的机制:多态消息,可以灵活而清晰地表达条件逻辑。将条件逻辑转化为消息形式,往往能降低代码的重复、增加清晰度并提高弹性。
找到不值得的间接层,并将它拿掉。(最终只一处用)
重构的难题
数据库
修改接口
让旧接口继续工作。请尽量这么做:让旧接口调用新接口。当你要修改某个函数名称时,请留下旧函数,让它调用新函数。Java中有deprecation
不建议使用。
不要过早发布接口,请修改你的代码所有权政策,使重构更畅顺。
Java还有一种特别的接口修改:在throws子句中增加一个异常。通常,我总喜欢为整个包(package)定义一个异类基(就像java.sql的SQLEception)。
最开始设计要花多少时间
先想象设计重构为另一个设计的难度有多大?如果看上去简单,那么就不必太担心选择是否得当,于是我就会选最简单的设计,哪怕它不能覆盖所有潜在的需求也没关系。但如果预先看不到简单的重构办法,我就会在设计投入更多力气。不过我发现,后一种情况很少出现。
何时不该重构
重构它还不如重新写一个来得简单。
重构之前,代码必须起码能够在大部分情况下正常运作。
将“大块头软件”重构为封装良好的小型组件。
如果项目已近最后期限,你也应该避免重构。
比喻:重构工作是“债务”,公司可以借债,但不要过重。
多个项目经验显示:重构的确能够提高生产力。如果你最后没有足够时间,通常表示你其实早该进行重构。
重构与设计
如果问“把一个简单的解决方案重构成一个灵活的方法有多大难度?” 如果答案是“相当容易”(大多数时候都如此),那么你就可以只需实现目前的简单方案就行了。
哪怕你完全了解系统,也请实际度量它的性能,不要臆测。
重构与性能
重构,使软件的性能优化更容易。除了对性能有严格要求的实时系统,其他任何情况下“编写快速软件”的秘密就是:首先写出可调的软件,然后调整它以求获得足够速度。
三种编写快速软件的方法
最严的是时间预算法
持续关注法 事与愿违,因为性能改善一旦分散到程序各角落,每次改善都只不过是从对程序行为的一个狭隘视角出发而已。
通常,大半时间都耗费在一小半代码身上。
- 统计数据,直至进入性能优化阶段(后期),再按照某个特定程序来调整程序性能。
需要一个度量工具,找出大量消耗时间和空间的性能热点。小幅度改进,测试,度量。
良好构造的程序可以优化这一过程。
有比较充裕的时间调整性能,可以更快添加功能。
可以在性能分析时便有较细的粒度。更好的理解选择,更清楚哪种调整起关键作用。
本节,我们把重构看做整个软件开发过程的一个关键环节。
我发现重构可以帮助我写出更快的软件。短期看来,重构的确可能使软件变慢,但它使优化阶段的软件性能调整更容易,最终还是会得到好的效果。
说明
《重构-改善既有代码的设计》Martin Fowler 摘要: 第二章 重构的原则
你也可以访问:http://txidol.github.io 获取更多的信息
SQL SELECT TOP 子句
SELECT TOP 子句用于规定要返回的记录的数目。
SELECT TOP 子句对于拥有数千条记录的大型表来说,是非常有用的。
注释:并非所有的数据库系统都支持 SELECT TOP 子句。
SQL Server / MS Access 语法
SELECT TOP number|percent column_name(s)
FROM table_name;
MySQL 语法
SELECT column_name(s)
FROM table_name
LIMIT number;
实例
SELECT *
FROM Persons
LIMIT 5;
Oracle 语法
SELECT column_name(s)
FROM table_name
WHERE ROWNUM <= number;
实例
SELECT *
FROM Persons
WHERE ROWNUM <=5;
MongoDB 语法
db.users.findOne()
or
db.users.find().limit(1)
重构概览
所谓重构(refactoring
)是这样一个过程:在不改变代码外在行为的前提下,对代码做出修改,以改进程序的内部结构。
摘要
如果你发现自己需要为程序添加一个特性,而代码结构使你无法很方便地达成目录,那就先重构那个程序,使特性的添加比较容易进行,然后再添加特性。
代码块愈小,代码的功能就愈容易管理,代码的处理和移动也就愈轻松。
Extract Method
提炼到独立方法中
重构技术就是以微小的步伐修改程序,如果你放下错误,很容易可发现它。
任何一个傻瓜都能写出计算机可以理解的代码,唯有写出人类容易理解的代码,才是优秀的程序员。
Move Method
绝大多数情况下,函数应该放在它们所使用的数据的所属对象内。“适应新家”,意味着去掉参数,变更函数名。
Replace Temp with Query
临时变量直接用查询方法代替。
Form Template Method
?
最好不要在另一个对象的属性基础上运用switch语句。如果不得不使用,也应该在对象自己的数据上使用,而不是在别人的数据上使用。
可以用多态取代switch语句,或者State模式,加入间接层
Replace Type Code with State/Strategy
使用状态或策略模式替换类型代码
Replace Conditional with Polymorphism
使用多态替换条件,去掉switch
Self Encapsulate Filed
自己内部属性用封装方法来处理
一次简单的重构:
Extract Method
抽取方法Move Method
移动方法Replace Conditional with Polymorphism
多态替换条件Self Encapsulate Filed
自属性封装Replace Type Code with State/Strategy
使用状态或策略模式替换类型
说明
《重构-改善既有代码的设计》Martin Fowler 第一章摘要
欢迎修改地址:https://github.com/txidol/txidol.github.io
你也可以访问:http://txidol.github.io 获取更多的信息