Kx systems公司的创始人之一Arthur Whitney在2003年研发了列式数据库KDB和它的操作语言q。q也可以写成Q。设计之初,q语言要做到简洁,高效和富表达性。
 
q的起源受到多种语言的启示。包括APL、LISP和函数式编程。
APL是一个向量语言,所以Q也具有向量语言的一些特点:
- 处理大批量数据时非常快
 - 处理数据的基本单元 - 列表
 
Q不只于此,q在处理关系型数据时也非常快。q支持SQL 92标准,并在这个基础上加上了一些特有的sql特性和丰富的内置函数。
 LISP语言处理的数据是通过list这种形式,q同样是通过list的形式。另外q还拥有许多函数式编程的特点。虽然q并不完全是一个函数式编程语言,但函数编程之于q,相当于面向对象之于Java/C#。
 
Q特点
Q设计的时候,考虑到现有数据处理系统的弊端。事实上我们现在涉及数据处理的系统,面临着非常复杂的数据转化过程。例如:
- 从对象转到数据库表
 - 从对象转到网络传输模型(xml)
 - 各种各样的类
 
。q的出现能够较好的解决这些问题。Q的设计思想与之前所学的大部分语言是如此的不同,以至于我们在这里有必要让大家先调整好思维方式再去查看语法细节。如果用一句话来描述q的特点,它是.....。许多各种各样的特点
-  内存内的数据库:理解KDB的一种方式就是KDB是一个内存数据库,但拥有磁盘可持久化能力。
 -  解释性语言 :开发周期更短
 -  列表是有顺序的 :不同于数据库中的行,因为列表有序,所以数据表也有序
 -  从右往左解析 
 - 面向表
 - 面向列:关系型数据库按行处理数据和存储数据,kdb是按列存数据,对数据进行运算也是直接作用在列向量上。
 - 强类型
 -  Null值拥有特殊含义 
 - 内置I/O的支持
 
数学复习课
q语言和数据的相关性太紧密了,以至于我在这里有必要复习一下一些基本的数据函数知识。实际上,绝大部分的q结构和操作都可以理解为方法映射。
对于一个函数,其输入值组成的域称为domain,值域称为range。通常我们有两种方式来描述算法/方法。一是公式法,可以写成
 f(x) = x2 
 
 另外一个是图形表示
 
| I | O | 
| 0 | 0 | 
| 1 | 1 | 
| 2 | 4 | 
| 3 | 9 | 
  其中I是输入,O是输出。  
 
根据函数参数数量的不同,我们又将函数分成几类:
- monadic:只有一个参数
 - dyadic:有两个参数
 -  nildic:没有参数
 
如果一个g的值域是f的domain,那么这个函数组合可以写成f(g(x))。
(在下文中,我们称数学函数为map/mapping,称q方法为function。
简单操作
从官方网站下载试用版本后,解压相应的文件到安装目录,例如在windows上推荐解压到c盘。
 然后打开命令窗口,切换到如下目录,并执行q。
 
 
变量: 与其他语言相似,变量也是用于存储和表示数据的地方。在q中,变量的声明和赋值在一个语句中完成。变量的赋值符,并不是=,而是:q变量必须以字母开头,可包含字母,_和数字。
命名规则推荐:
           使用动词表示操作符和方法,使用名词表示数据 
 
使用较为简洁的名字。Use contexts for namespacing.
 q的专业编写人员总是会省略掉很多不必要的空格。但这并不一定是强制的要求,我们可以在提高可读性的情况下,加入一些空格。比较推荐加空格的地方包括,逗号,分号和juxpositon后面。
 
在q里面,语言的注释是通过/来完成的。另外注释符和表达式之间需要一个空格来分割。
变量类型
 q的变量其实并不带类型信息。类型信息附属在变量的那种之上。
 
初次使用q的人,肯定会被他的解析顺序所迷惑。例如下面这样的表达式,对于其他语言的使用者来说肯定是前所未闻的:
q) 1+a:43
44
q将表达式从右向左解析。所以这个表达式可以理解为 将43赋值给a,再将a加上1,最后向console 打印结果。在q中,表达式是允许一个刚刚被赋值的变量参与运算的。
 
 
Atoms
All data is ultimately built from atoms, so we begin with atoms.An atom is an irreducible value with a specific data type.
the following table collects all important information for q data type and atoms:
| type | size | char type | num type | notation | null value | 
| boolean | 1 | b | 1 | 1b | 0b | 
| byte | 1 | x | 4 | 0x26 | 0x00 | 
| short | 2 | h | 5 | 42h | 0Nh | 
| int | 4 | i | 6 | 42 | 0N | 
| long | 8 | j | 7 | 42j | 0Nj | 
| real | 4 | e | 8 | 4.2e | 0Ne | 
| float | 8 | f | 9 | 4.2 | 0n | 
| char | 1 | c | 10 | "z" | " " | 
| symbol | * | s | 11 | ‘zaphod | ` | 
| month | 4 | m | 13 | 2006.07m | 0Nm | 
| date | 4 | d | 14 | 2006.07.21 | 0Nd | 
| datetime | 4 | z | 15 | 2006.07.21T09:13:39 | 0Nz | 
| minute | 4 | u | 17 | 23:59 | 0Nu | 
| second | 4 | v | 18 | 23:59:59 | 0Nv | 
| time | 4 | t | 19 | 09:01:02:042 | 0Nt | 
| enumeration |   |   | * | `u$v |   | 
| dictionary |   |   | 99 | `a`b`c!!10 20 30 |   | 
| table |   |   | 98 | ([] c1:ab`c; c2:10 20 30) | 
 
 
Integer data
int => 123
short=> 234h (h is compulsory)
long => -23423j (j is compulsory)
Type promotion is performed automatically in q primitive operations. However, if a specific integer type is required in a list and a narrower type is presented . then an error will be prompt.
 
 
floating point data
float => pi:3.23423 or pi:1f
real => 1.23423e
we can user scientific notation for both float and real.
By default, the q console displays only seven decimal digits of accuracy for float and real . we can change this by \P 12
binary data
boolean => bit:0b
byte => by:0x2a
charactor:
char => ch:"q" or ch:"\n"
symbol => s1:`q
note that symbol is the smallest unit of the data, can't be reduced.