2010年8月13日星期五

SQL LIKE 查询的一个问题

在做用户管理的时候,用户表(users) 有一个字段(dept)用来存储用户所在部门的信息, 字段的值一般是这样的,各级部门间使用横杠分隔:

XX宝-技术部
XX宝-技术部-数据仓库

我们的系统有一个根据用户所在部门进行过滤的功能,所以我们用了类似下面的查询语句:

SELECT * FROM users WHERE dept LIKE "XX宝-技术部%";

这样的性能还好,但是今天发现一个问题是,当有两个部门名称很相似,比如:

XX宝-CEO
XX宝-CEO办公室

这时在查询 XX宝CEO 的时候就会把 XX宝-CEO办公室 的用户也查询出来。

于是想到正则表达式:

SELECT *
FROM users
WHERE REGEXP_LIKE(dept, "^XX宝-CEO$")
OR REGEXP_LIKE(dept, "^XX宝-CEO-[\w\-]+");

合并正则表达式的另一解:

SELECT *
FROM users
WHERE REGEXP_LIKE(dept, "^XX宝-CEO($|-[\w\-]+)");

杯具的性能问题。

突然想到

SELECT *
FROM users
WHERE dept="XX宝-CEO"
OR dept LIKE "XX宝-CEO-%";

于是简单有效的解决了这个问题。

2010年8月1日星期日

用 gvim 比较 git diff

for Windows

参考 gist:502217

1. 在用户目录下的 .gitconfig 中加入:

[diff]
external = git_diff_wrapper.bat
[pager]
diff =

2. 创建 git_diff_wrapper.bat 文件放到 $PATH 目录下,内容为: 注意其中的 path\to\ 要改为 gvim.exe 所在目录。

path\to\gvim.exe -d "%2" "%5"

for Linux

参考 Git Diff with Vimdiff

2010年7月29日星期四

遍历字符的性能

  1. s.charAt(i)
  2. s.split("")[i]

Test

在 IE7, Firefox3.6.8, Chrome5.0, Safari5.0, Opera10 上测试, 除了 Firefox 之外,所有的浏览器均是第 2 种表达式更快速。

2010年7月23日星期五

使用 calendar.vim

最初看到明城 推荐使用 Vim Calendar 插件, 于是很小白的尝试了一下,然后就没有了然后。

最初尝试的过程已经基本忘记,恍惚记得在 Calendar 的日期上回车,窗户貌似在右侧窗口 打开的(后来发现我记错了,这是 Vimwiki-diary的支持);至于明城推荐设置的 ca 快捷键,后来才知道是与 text-object 冲突的。

再后来就用上了 Vimwiki,做个人 Wiki 之余,还用它的 diary 写日记。总体来说,Vimwiki 的 diary 是比较强大的,我甚至还提了几个被接受的建议。

但是随着使用的深入,发现通常 Wiki 项目下是不需要 diary 的,而 diary 也基本不需要 Wiki,把这两种整合在一起也许就是个错误。我们真正需要的是一个更强的 Calendar diary, 而不是 Wiki 附加的 diary 支持。

如果真的希望 Vimwiki 有 diary 的支持,我也希望这个 diary 和 Wiki 是相互独立的, Wiki 项目中无需 diary,diary 无需包含在每个 Wiki 项目里。

另外基于 Wiki 的原因,所有的 diary-wiki 文件都放在同一个目录下,当 diary 日渐增多, 目录变得臃肿起来也不是什么好事。

我需要的是一个更强的 Vim Calendar。基于这个想法,我便尝试着手增强 Calendar。 目前已经支持 :CalendarSearch 和更好的 diary 打开方式。更多的想法见 这里

2010年6月25日星期五

在 Vim 页签中打开文件

这两天折腾让文件在 Vim 的新页签中打开(类似 Firefox 等浏览器)的特性, 发现让文件在页签中打开有非常多的优点:

  1. 打开文件的速度更快(免去了启动 Vim 的时间)
  2. 占用内存等资源更少(单个 Vim 窗口比多个窗口节省资源)
  3. 任务栏更节省可用空间(不过 Windows 7 中还未支持任务栏多页签内容预览)。
  4. 编辑过程中文件间可以快速跳转,缓冲区也可以共享。

我参考前辈的方案,做了更 自动化的处理 脚本, 将其中的 edit.with.vim.tabs.reg 合并到注册表就可以了。如果想还原为用窗口打开的方式, 再将 edit.with.vim.window.reg 合并到注册表中。

这个设置会让双击默认编辑器为 Vim 的文件,或者右键 -> Edit with Vim 都将文件在页签中 打开。开始用着确实挺爽,右键菜单中也没有了那些动态增加进来的已打开的文件的菜单项。 不过后来又发现不止如此,连“用 Vim 比较”(Diff with Vim)的项也没了。

重装了好几次,终于搞清楚了一些东西。注册表的

[HKEY_CLASSES_ROOT\*\shellex\ContextMenuHandlers\gvim]
@="{51EEE242-AD87-11d3-9C1E-0090278BBD99}"

是关键项,他根据 gvimext.dll 来附加右键菜单的动态项,包括 Diff with Vim。 如果你不想有默认的新窗口中打开文件的“用 Vim 编辑 (&V)”(Edit with Vim), 就需要把上面这项删除,不过这也会殃及 Diff with Vim。

我实在没有特别好的办法,我在注册表中做了一个 "Diff with Vim" 的项,但是这个菜单命令 会针对选中的多个文件各自执行一次;而不是执行一次,并将多个选中的文件作为参数 一次传入。这个肯定也能做到的,参看 Vim 默认的行为,和 WinMerge 等就知道,只求高手来帮忙了。

我目前不希望没有这个选中多个文件并 Diff 的功能(虽然它连快捷键都没有), 所以只好保留了这个注册表项,为了避免快捷键冲突,只好修改了在页签中打开文件的 注册表项的快捷键。

或者用其他的文本比较工具,如 WinMerge,BeyondCompare。这样的话,直接删除上面的注册表项。

如果你有好主意,快来快来告诉我 : )

其他

另外给页签加上序号是非常有用的:

set guitablabel=%N.%t

尤其是在设置了这样的快捷键之后:

imap  :tabnext
nmap :tabnext
imap :tabprevious
nmap :tabprevious
imap :tabfirst
nmap :tabfirst
imap 2gt
nmap 2gt
imap 3gt
nmap 3gt
imap 4gt
nmap 4gt
imap 5gt
nmap 5gt
imap 6gt
nmap 6gt
imap 7gt
nmap 7gt
imap 8gt
nmap 8gt
imap 9gt
nmap 9gt
imap :tablast
nmap :tablast

更多,但是不推荐(因为跟默认快捷键冲突)的快捷键设置:

" [CONFLICT] back tag history
imap :tabnew
nmap :tabnew
" [CONFLICT] window shortcut key.
imap :tabclose
nmap :tableclose
imap :tabonly
nmap :tabonly

更新 (2010/6/26)

今天想折腾一下 gvimext.dll ,因为这个是问题的本源,只要将它里面的“用 Vim 编辑”(Edit with Vim)加上参数, 改成新页签中打开的方式就好了,而且选中多个文件进行比较,好像也必须使用动态连接库的方式实现, 于是找到了这个 gvimext.dll 它让 Vim 7 支持新页签中打开。试用了一下,感觉有点啰嗦了,它让新窗口和新页签打开文件的方式共存,并且快捷键 仍然设置在新窗口打开的菜单项上。不过里面带有源码,我们可以改成自己喜欢的方式。

参考链接

2010年6月20日星期日

Vim 自动补全成对的括号和引号

炫日分享了一个 自 动补全成对的括号 的脚本,【注】:原文代码中引号被转义成了中文引号,下面是修正后的脚本。

inoremap ( ()i
inoremap ) =ClosePair(')')
inoremap { {}i
inoremap } =ClosePair('}')
inoremap [ []i
inoremap ] =ClosePair(']')
inoremap < <>i
inoremap > =ClosePair('>')

function ClosePair(char)
if getline('.')[col('.') - 1] == a:char
return "\"
else
return a:char
endif
endf

经此启发我增加了对括号和引号更智能的补全支持, 不过中文全角的括号和引号目前无法通过映射来实现, 对于跨行、转义的符号对的支持也不佳,如果有好的实现也请告知 : )

  • OpenPair:
    1. 如果当前行的括号已经成对匹配,则自动补全右括号 (I)
    2. 如果左括号比右括号多,则自动补全 I(() (I() ((I) (()I
    3. 如果左括号比右括号少,
      I()) 原样输出,不自动补全
      (I)) 同上
      ()I) 同上
      ())I 自动补全:左括号较少,且光标之后字符串进行一次递归上面的条件
  • ClosePair:
    1. 如果光标之后是一个右括号,向右移动一列 (I) ((I) (I)) ()I)
    2. 否则原样输出。

代码见 gist: 449512

更新 (2010/6/24) 最后更新 (2010/7/9)

相关脚本

2010年6月16日星期三

在 Google Maps 的街景视图里看实况足球

我承认我标题党了,这只是我的一个 idea 而已,并没有实际实现。

前几天有新闻称日本要申办 2022 年的世界杯,承诺将以 3D 转播赛况,还以全息技术将赛况投影到足球场上, 任何一个足球场都可以模拟现场实况,并准备研发全息电视,把赛况以全息技术在家庭里播放。 而实际上,日本在某些音乐会已经使用全息技术的实际应用(X-Japan的 Art of Life 的 15:36 至 19:13 之间都是以全息技术 制作的演出,直接观看19:10,然后等几秒钟就会明白)。

我的个神啊,这是一种怎样的未来。

在看南非世界杯的几个球场街景视图时,我突然想到如果模拟实况足球游戏,根据比赛实况,将比赛情形在类似的视图中 展现出来,会爽到什么程度啊。

伊 丽莎白港

内 尔斯普雷特

p.s. 现在的 Google Maps 街景视图,比 Google Earth 的 3D 模型要爽要逼真,不过街景视图无法以 3D 效果看鸟瞰图。

延伸阅读: