KDB+ - 快速指南
KDB+ - Overview
这是对来自kx系统的kdb+的完全嘲讽,主要针对那些独立学习的人。 kdb +,于2003年推出,是新一代的kdb数据库,用于捕获,分析,比较和存储数据。
kdb +系统包含以下两个组件 -
KDB+ - 数据库(k数据库加)
Q - 使用kdb +的编程语言
kdb+和q都是用k programming language编写的(与q相同但可读性较差)。
Background
Kdb +/q起源于一种不起眼的学术语言,但多年来,它逐渐提高了用户友好性。
APL (1964,编程语言)
A+ (1988年,由Arthur Whitney修改的APL)
K (1993年,A +的清晰版,由A. Whitney开发)
Kdb (1998,基于内存列的数据库)
Kdb+/q (2003,q语言 - k的可读版本)
为什么以及在哪里使用KDB +
为什么? - 如果您需要使用单一解决方案来获取分析的实时数据,那么您应该考虑使用kdb +。 Kdb +将数据库存储为普通本机文件,因此它对硬件和存储架构没有任何特殊需求。 值得指出的是,数据库只是一组文件,因此您的管理工作并不困难。
在哪里使用KDB + ? - 很容易计算哪些投资银行不使用kdb +,因为大多数投资银行目前正在使用或计划从传统数据库切换到kdb +。 随着数据量日益增加,我们需要一个可以处理大量数据的系统。 KDB +满足了这一要求。 KDB +不仅可存储大量数据,还可实时分析数据。
入门
有了这么多背景知识,现在让我们阐述并学习如何为KDB +建立一个环境。 我们将从如何下载和安装KDB +开始。
下载和安装KDB +
您可以从http://kx.com/software-download.php获得免费的32位版KDB +,以及64位版本的所有功能。
同意许可协议,选择操作系统(适用于所有主要操作系统)。 对于Windows操作系统,最新版本为3.2。 下载最新版本。 解压缩后,您将获得文件夹名称“windows” ,在Windows文件夹中,您将获得另一个文件夹“q” 。 将整个q文件夹复制到c:/驱动器上。
打开“运行”终端,键入存储q文件夹的位置; 它会像“c:/q/w32/q.exe”。 点击Enter后,您将获得一个新控制台,如下所示 -
在第一行,您可以看到版本号为3.2,发布日期为2015.03.05
目录布局
试用版/免费版通常安装在目录中,
For linux/Mac −
~/q /main q directory (under the user’s home)
~/q/l32 /location of linux 32-bit executable
~/q/m32 /Location of mac 32-bit executable
For Windows −
c:/q /Main q directory
c:/q/w32/ /Location of windows 32-bit executable
Example Files −
下载kdb +后,Windows平台中的目录结构如下所示 -
在上面的目录结构中, trade.q和sp.q是我们可以用作参考点的示例文件。
KDB+ - Architecture
Kdb +是一个高性能,高容量的数据库,从一开始就设计用于处理大量数据。 它完全是64位,并具有内置的多核处理和多线程。 相同的架构用于实时和历史数据。 数据库包含自己强大的查询语言q,因此可以直接在数据上运行分析。
kdb+tick是一种允许捕获,处理和查询实时和历史数据的体系结构。
Kdb +/tick体系结构
下图提供了典型Kdb +/tick体系结构的概括,随后是各种组件的简要说明和数据的直通流程。
数据馈送是一个时间序列数据,主要由路透社,彭博社或直接来自交易所的数据馈送提供商提供。
为了获得相关数据,来自数据馈送的数据由feed handler解析。
一旦数据由Feed处理程序解析,它就会转到ticker-plant 。
要从任何故障中恢复数据,股票代码工厂首先将新数据更新/存储到日志文件,然后更新其自己的表。
在更新内部表和日志文件之后,将持续时间循环数据连续发送/发布到实时数据库和请求数据的所有链式订户。
在工作日结束时,将删除日志文件,创建新日志文件并将实时数据库保存到历史数据库中。 将所有数据保存到历史数据库后,实时数据库将清除其表。
Kdb + Tick体系结构的组件
数据Feed
数据馈送可以是任何市场或其他时间序列数据。 将数据馈送视为馈送处理程序的原始输入。 可以直接来自交换(实时流数据),来自新闻/数据提供商,如汤森路透,彭博社或任何其他外部机构。
Feed Handler
馈送处理程序将数据流转换为适合写入kdb +的格式。 它连接到数据源,它检索数据并将数据从特定于Feed的格式转换为Kdb +消息,该消息将发布到自动收录机工厂流程。 通常,饲料处理程序用于执行以下操作 -
- 根据一组规则捕获数据。
- 将数据从一种格式转换(/充实)到另一种格式。
- 抓住最新的价值观。
自动收报机
Ticker Plant是KDB +架构中最重要的组件。 它是实时数据库或直接订户(客户)连接的股票代码工厂,用于访问财务数据。 它在publish and subscribe机制中运行。 获得订阅(许可证)后,将定义发布者(代码工厂)的勾选(常规)发布。 它执行以下操作 -
从Feed Handler接收数据。
在股票代码工厂收到数据后,它立即将副本存储为日志文件,并在代码工厂获得任何更新后对其进行更新,以便在出现任何故障时,我们不应该有任何数据丢失。
客户(实时订户)可以直接订阅自动收报机。
在每个工作日结束时,即,一旦实时数据库收到最后一条消息,它就将所有今天的数据存储到历史数据库中,并将其推送给已订阅当前数据的所有订户。 然后它重置所有表。 一旦将数据存储在历史数据库或其他直接链接的订户中,就会删除日志文件到实时数据库(rtdb)。
因此,自动收报机,实时数据库和历史数据库全天候运行。
由于股票代码工厂是Kdb +应用程序,因此可以像使用任何其他Kdb +数据库一样使用q查询其表。 所有自动收报机工厂客户端只能作为订户访问数据库。
Real-Time Database
实时数据库(rdb)存储今天的数据。 它直接连接到自动收报机工厂。 通常,它将在市场时间(一天)内存储在内存中,并在一天结束时写入历史数据库(hdb)。 由于数据(rdb数据)存储在内存中,处理速度非常快。
由于kdb +建议RAM大小是每天预期数据大小的四倍或更多倍,因此在rdb上运行的查询速度非常快,并且性能优越。 由于实时数据库仅包含今天的数据,因此不需要日期列(参数)。
例如,我们可以有rdb查询,如,
select from trade where sym = `ibm
OR
select from trade where sym = `ibm, price > 100
历史数据库
如果我们必须计算公司的估算值,我们需要提供其历史数据。 历史数据库(hdb)保存过去完成的事务的数据。 每个新的一天的记录将在一天结束时添加到hdb。 hdb中的大表要么以sppeded的形式存储(每列存储在自己的文件中),要么存储由时态数据分区。 还可以使用par.txt (文件)进一步分区一些非常大的数据库。
这些存储策略(展开,分区等)在从大型表中搜索或访问数据时非常有效。
历史数据库还可用于内部和外部报告目的,即用于分析。 例如,假设我们想要从交易(或任何)表名称获取IBM特定日期的公司交易,我们需要编写如下查询 -
thisday: 2014.10.12
select from trade where date = thisday, sym =`ibm
Note - 一旦我们得到q语言的概述,我们将编写所有这些查询。
Q Programming Language
Kdb +带有内置的编程语言,即q 。 它包含标准SQL的超集,可扩展用于时间序列分析,并提供许多优于标准版本的优势。 熟悉SQL的人可以在几天内学习q并能够快速编写自己的即席查询。
启动“q”环境
要开始使用kdb +,您需要启动q会话。 启动q会话有三种方法 -
只需在运行终端上输入“c:/q/w32/q.exe”即可。
启动MS-DOS命令终端并键入q 。
将q.exe文件复制到“C:\Windows\System32”,然后在运行终端上输入“q”。
在这里,我们假设您正在使用Windows平台。
数据类型 (Data Types)
下表提供了支持的数据类型列表 -
名称 | 例 | 烧焦 | 类型 | 尺寸 |
---|---|---|---|---|
boolean | 1b | b | 1 | 1 |
byte | 0xff | x | 4 | 1 |
short | 23h | h | 5 | 2 |
int | 23i | i | 6 | 4 |
long | 23j | j | 7 | 8 |
real | 2.3e | e | 8 | 4 |
float | 2.3f | f | 9 | 8 |
char | “a” | c | 10 | 1 |
varchar | `ab | s | 11 | * |
month | 2003.03m | m | 13 | 4 |
date | 2015.03.17T18:01:40.134 | z | 15 | 8 |
minute | 08:31 | u | 17 | 4 |
second | 08:31:53 | v | 18 | 4 |
time | 18:03:18.521 | t | 19 | 4 |
enum | `u $`b,其中你:`a`b | * | 20 | 4 |
原子和列表形成
原子是单个实体,例如,单个数字,字符或符号。 在上表(不同数据类型)中,所有支持的数据类型都是原子。 列表是原子序列或其他类型,包括列表。
将任何类型的原子传递给monadic(即单个参数函数)类型函数将返回负值,即–n ,而将这些原子的简单列表传递给type函数将返回正值n 。
例1 - 原子和列表形成
/ Note that the comments begin with a slash “/” and cause the parser
/ to ignore everything up to the end of the line.
x: `mohan /`mohan is a symbol, assigned to a variable x
type x /let’s check the type of x
-11h /-ve sign, because it’s single element.
y: (`abc;`bca;`cab) /list of three symbols, y is the variable name.
type y
11h /+ve sign, as it contain list of atoms (symbol).
y1: (`abc`bca`cab) /another way of writing y, please note NO semicolon
y2: (`$”symbols may have interior blanks”) /string to symbol conversion
y[0] /return `abc
y 0 /same as y[0], also returns `abc
y 0 2 /returns `abc`cab, same as does y[0 2]
z: (`abc; 10 20 30; (`a`b); 9.9 8.8 7.7) /List of different types,
z 2 0 /returns (`a`b; `abc),
z[2;0] /return `a. first element of z[2]
x: “Hello World!” /list of character, a string
x 4 0 /returns “oH” i.e. 4th and 0th(first)
element
Q Language - Type Casting
通常需要将某些数据的数据类型从一种类型更改为另一种类型。 标准的转换函数是“$” dyadic operator 。
使用三种方法从一种类型转换为另一种类型(字符串除外) -
- 通过其符号名称指定所需的数据类型
- 按字符指定所需的数据类型
- 通过短值指定所需的数据类型。
将整数转换为浮点数
在以下将整数转换为浮点数的示例中,所有三种不同的转换方式都是等效的 -
q)a:9 18 27
q)$[`float;a] /Specify desired data type by its symbol name, 1<sup>st</sup> way
9 18 27f
q)$["f";a] /Specify desired data type by its character, 2<sup>nd</sup> way
9 18 27f
q)$[9h;a] /Specify desired data type by its short value, 3<sup>rd</sup> way
9 18 27f
检查这三个操作是否相同,
q)($[`float;a]~$["f";a]) and ($[`float;a] ~ $[9h;a])
1b
将字符串转换为符号
将字符串转换为符号反之亦然。 让我们用一个例子来检查 -
q)b: ("Hello";"World";"HelloWorld") /define a list of strings
q)b
"Hello"
"World"
"HelloWorld"
q)c: `$b /this is how to cast strings to symbols
q)c /Now c is a list of symbols
`Hello`World`HelloWorld
尝试使用键控字符号或符号11h将字符串强制转换为符号将失败,类型错误 -
q)b
"Hello"
"World"
"HelloWorld"
q)`symbol$b
'type
q)11h$b
'type
将字符串转换为非符号
将字符串转换为符号以外的数据类型的方法如下 -
q)b:900 /b contain single atomic integer
q)c:string b /convert this integer atom to string “900”
q)c
"900"
q)`int $ c /converting string to integer will return the
/ASCII equivalent of the character “9”, “0” and
/“0” to produce the list of integer 57, 48 and
/48.
57 48 48i
q)6h $ c /Same as above
57 48 48i
q)"i" $ c /Same a above
57 48 48i
q)"I" $ c
900i
因此,要将整个字符串(字符列表)强制转换为单个数据类型x需要我们指定表示数据类型x的大写字母作为$运算符的第一个参数。 如果以任何其他方式指定x的数据类型,则会导致将强制转换应用于字符串的每个字符。
Q Language - Temporal Data
q语言有许多不同的方式来表示和操纵时间数据,例如时间和日期。
Date
kdb +中的日期在内部存储为自我们的参考日期为01Jan2000以来的整数天数。 此日期之后的日期在内部存储为正数,之前的日期作为负数引用。
默认情况下,日期以“YYYY.MM.DD”格式写入
q)x:2015.01.22 /This is how we write 22nd Jan 2015
q)`int$x /Number of days since 2000.01.01
5500i
q)`year$x /Extracting year from the date
2015i
q)x.year /Another way of extracting year
2015i
q)`mm$x /Extracting month from the date
1i
q)x.mm /Another way of extracting month
1i
q)`dd$x /Extracting day from the date
22i
q)x.dd /Another way of extracting day
22i
Arithmetic and logical operations可以直接在日期执行。
q)x+1 /Add one day
2015.01.23
q)x-7 /Subtract 7 days
2015.01.15
2000年1月1日星期六下降。 因此,整个历史中的任何星期六或将来除以7时,将产生0的余数,星期日给出1,星期一产量2。
Day mod 7
Saturday 0
Sunday 1
Monday 2
Tuesday 3
Wednesday 4
Thursday 5
Friday 6
Times
时间内部存储为自午夜行程以来的整数毫秒数。 时间以HH:MM:SS.MSS格式写入
q)tt1: 03:30:00.000 /tt1 store the time 03:30 AM
q)tt1
03:30:00.000
q)`int$tt1 /Number of milliseconds in 3.5 hours
12600000i
q)`hh$tt1 /Extract the hour component from time
3i
q)tt1.hh
3i
q)`mm$tt1 /Extract the minute component from time
30i
q)tt1.mm
30i
q)`ss$tt1 /Extract the second component from time
0i
q)tt1.ss
0i
与日期一样,算术可以直接执行。
Datetimes
日期时间是日期和时间的组合,以ISO标准格式的“T”分隔。 日期时间值存储从2000年1月1日午夜开始的小数日计数。
q)dt:2012.12.20T04:54:59:000 /04:54.59 AM on 20thDec2012
q)type dt
-15h
q)dt
2012.12.20T04:54:59.000
9
q)`float$dt
4737.205
可以通过转换为浮动来获得基础分数日计数。
Q Language - Lists
列表是q language的基本构建块,因此对列表的透彻理解非常重要。 列表只是原子(原子元素)和其他列表(一个或多个原子的组)的有序集合。
列表类型
general list其项目括在匹配的括号中,并用分号分隔它们。 例如 -
(9;8;7) or ("a"; "b"; "c") or (-10.0; 3.1415e; `abcd; "r")
如果列表包含相同类型的原子,则称为uniform list 。 否则,它被称为general list (混合类型)。
Count
我们可以通过计数获得列表中的项目数。
q)l1:(-10.0;3.1415e;`abcd;"r") /Assigning variable name to general list
q)count l1 /Calculating number of items in the list l1
4
简单列表的示例
q)h:(1h;2h;255h) /Simple Integer List
q)h
1 2 255h
q)f:(123.4567;9876.543;98.7) /Simple Floating Point List
q)f
123.4567 9876.543 98.7
q)b:(0b;1b;0b;1b;1b) /Simple Binary Lists
q)b
01011b
q)symbols:(`Life;`Is;`Beautiful) /Simple Symbols List
q)symbols
`Life`Is`Beautiful
q)chars:("h";"e";"l";"l";"o";" ";"w";"o";"r";"l";"d")
/Simple char lists and Strings.
q)chars
"hello world"
**Note − A simple list of char is called a string.
列表包含原子或列表。 To create a single item list ,我们使用 -
q)singleton:enlist 42
q)singleton
,42
To distinguish between an atom and the equivalent singleton ,请检查其类型的符号。
q)signum type 42
-1i
q)signum type enlist 42
1i
Q Language - Indexing
列表按其项目的位置从左到右排序。 项目从列表开头的偏移量称为index 。 因此,第一项具有索引0,第二项(如果有一个)具有索引1等。计数列表n具有从0到n–1索引域。
索引表示法
给定列表L ,索引i处的项目由L[i]访问。 通过索引检索项目称为item indexing 。 例如,
q)L:(99;98.7e;`b;`abc;"z")
q)L[0]
99
q)L[1]
98.7e
q)L[4]
"z
索引分配
列表中的项目也可以通过项目索引进行分配。 从而,
q)L1:9 8 7
q)L1[2]:66 /Indexed assignment into a simple list
/enforces strict type matching.
q)L1
9 8 66
来自变量的列表
q)l1:(9;8;40;200)
q)l2:(1 4 3; `abc`xyz)
q)l:(l1;l2) /combining the two list l1 and l2
q)l
9 8 40 200
(1 4 3;`abc`xyz)
加入列表
两个列表上最常见的操作是将它们连接在一起以形成更大的列表。 更确切地说,连接运算符(,)将其右操作数附加到左操作数的末尾并返回结果。 它在任一参数中接受一个原子。
q)1,2 3 4
1 2 3 4
q)1 2 3, 4.4 5.6 /If the arguments are not of uniform type,
/the result is a general list.
1
2
3
4.4
5.6
Nesting
通过使用列表作为列表项来构建数据复杂性。
Depth
列表的嵌套级别称为深度。 原子的深度为0,简单列表的深度为1。
q)l1:(9;8;(99;88))
q)count l1
3
这是深度3的列表,有两个项目 -
q)l5
9
(90;180;900 1800 2700 3600)
q)count l5
2
q)count l5[1]
3
深度索引
可以直接索引嵌套列表的项目。
Repeated Item Indexing
通过单个索引检索项目始终从嵌套列表中检索最上面的项目。
q)L:(1;(100;200;(300;400;500;600)))
q)L[0]
1
q)L[1]
100
200
300 400 500 600
由于结果L[1]本身就是一个列表,我们可以使用单个索引检索其元素。
q)L[1][2]
300 400 500 600
我们可以再次重复单个索引以从最里面的嵌套列表中检索项目。
q)L[1][2][0]
300
你可以这样读,
Get the item at index 1 from L, and from it retrieve the item at index 2, and from it retrieve the item at index 0.
Notation for Indexing at Depth
对于重复索引嵌套列表的组成部分,有另一种表示法。 最后一次检索也可以写成,
q)L[1;2;0]
300
通过索引分配也适用于深度。
q)L[1;2;1]:900
q)L
1
(100;200;300 900 500 600)
Elided指数
Eliding Indices for a General List
q)L:((1 2 3; 4 5 6 7); (`a`b`c;`d`e`f`g;`0`1`2);("good";"morning"))
q)L
(1 2 3;4 5 6 7)
(`a`b`c;`d`e`f`g;`0`1`2)
("good";"morning")
q)L[;1;]
4 5 6 7
`d`e`f`g
"morning"
q)L[;;2]
3 6
`c`f`2
"or"
Interpret L[;1;] as,
检索顶级每个列表的第二个位置中的所有项目。
Interpret L[;;2] as,
检索第二级每个列表的第三个位置的项目。
Q Language - Dictionaries
字典是列表的扩展,为创建表提供了基础。 在数学术语中,字典创建了
“域→范围”
或者一般(简称)创造
“关键→价值”
元素之间的关系。
字典是键值对的有序集合,大致相当于哈希表。 字典是由域列表和范围列表之间通过位置对应关系定义的显式I/O关联定义的映射。 字典的创建使用“xkey”原语(!)
ListOfDomain ! ListOfRange
最基本的字典将简单列表映射到简单列表。
输入(I) | 输出(O) |
---|---|
`Name | `John |
`Age | 36 |
`Sex | “M” |
Weight | 60.3 |
q)d:`Name`Age`Sex`Weight!(`John;36;"M";60.3) /Create a dictionary d
q)d
Name | `John
Age | 36
Sex | "M"
Weight | 60.3
q)count d /To get the number of rows in a dictionary.
4
q)key d /The function key returns the domain
`Name`Age`Sex`Weight
q)value d /The function value returns the range.
`John
36
"M"
60.3
q)cols d /The function cols also returns the domain.
`Name`Age`Sex`Weight
Lookup
查找对应于输入值的字典输出值被称为looking up输入。
q)d[`Name] /Accessing the value of domain `Name
`John
q)d[`Name`Sex] /extended item-wise to a simple list of keys
`John
"M"
使用Verb查找@
q)d1:`one`two`three!9 18 27
q)d1[`two]
18
q)d1@`two
18
字典操作
修改和Upsert
与列表一样,可以通过索引分配修改字典的项目。
d:`Name`Age`Sex`Weight! (`John;36;"M";60.3)
/A dictionary d
q)d[`Age]:35 /Assigning new value to key Age
q)d
/New value assigned to key Age in d
Name | `John
Age | 35
Sex | "M"
Weight | 60.3
可以通过索引分配扩展字典。
q)d[`Height]:"182 Ft"
q)d
Name | `John
Age | 35
Sex | "M"
Weight | 60.3
Height | "182 Ft"
使用Find(?)反向查找
find(?)运算符用于通过将一系列元素映射到其domain元素来执行反向查找。
q)d2:`x`y`z!99 88 77
q)d2?77
`z
如果列表的元素不是唯一的,则find返回从域列表映射到它的第一个项目。
删除条目
要从字典中delete ( _ ) function条目,请使用delete ( _ ) function 。 (_)的左操作数是字典,右操作数是键值。
q)d2:`x`y`z!99 88 77
q)d2 _`z
x| 99
y| 88
如果第一个操作数是变量,则_的左侧需要空格。
q)`x`y _ d2 /Deleting multiple entries
z| 77
列字典
列字典是创建表的基础。 考虑以下示例 -
q)scores: `name`id!(`John`Jenny`Jonathan;9 18 27)
/Dictionary scores
q)scores[`name] /The values for the name column are
`John`Jenny`Jonathan
q)scores.name /Retrieving the values for a column in a
/column dictionary using dot notation.
`John`Jenny`Jonathan
q)scores[`name][1] /Values in row 1 of the name column
`Jenny
q)scores[`id][2] /Values in row 2 of the id column is
27
翻阅字典
翻转列字典的净效果只是反转索引的顺序。 这在逻辑上等同于转置行和列。
翻转列字典
通过应用一元翻转算子获得字典的转置。 看看下面的例子 -
q)scores
name | John Jenny Jonathan
id | 9 18 27
q)flip scores
name id
---------------
John 9
Jenny 18
Jonathan 27
翻转翻译列字典
如果您将字典移调两次,则会获得原始字典,
q)scores ~ flip flip scores
1b
Q Language - Table
表是kdb +的核心。 表是作为字典实现的命名列的集合。 q tables是面向列的。
创建表
使用以下语法创建表 -
q)trade:([]time:();sym:();price:();size:())
q)trade
time sym price size
-------------------
在上面的示例中,我们没有指定每列的类型。 这将由第一次插入表中设置。
另一种方法,我们可以在初始化时指定列类型 -
q)trade:([]time:`time$();sym:`$();price:`float$();size:`int$())
或者我们也可以定义非空表 -
q)trade:([]sym:(`a`b);price:(1 2))
q)trade
sym price
-------------
a 1
b 2
如果方括号内没有列,如上例所示,则表是未unkeyed 。
要创建keyed table ,我们在方括号中插入keyed table的列。
q)trade:([sym:`$()]time:`time$();price:`float$();size:`int$())
q)trade
sym | time price size
----- | ---------------
也可以通过将值设置为各种类型的空列表来定义列类型 -
q)trade:([]time:0#0Nt;sym:0#`;price:0#0n;size:0#0N)
获取表信息
让我们创建一个交易表 -
trade: ([]sym:`ibm`msft`apple`samsung;mcap:2000 4000 9000 6000;ex:`nasdaq`nasdaq`DAX`Dow)
q)cols trade /column names of a table
`sym`mcap`ex
q)trade.sym /Retrieves the value of column sym
`ibm`msft`apple`samsung
q)show meta trade /Get the meta data of a table trade.
c | t f a
----- | -----
Sym | s
Mcap | j
ex | s
主键和键控表
键控表
键控表是一个字典,它将唯一键表中的每一行映射到值表中的相应行。 让我们举一个例子 -
val:flip `name`id!(`John`Jenny`Jonathan;9 18 27)
/a flip dictionary create table val
id:flip (enlist `eid)!enlist 99 198 297
/flip dictionary, having single column eid
现在创建一个包含eid作为键的简单键控表,
q)valid: id ! val
q)valid /table name valid, having key as eid
eid | name id
--- | ---------------
99 | John 9
198 | Jenny 18
297 | Jonathan 27
ForeignKeys
foreign key定义了从定义它的表的行到具有相应primary key的表的行的映射。
外键提供referential integrity 。 换句话说,尝试插入不在主键中的外键值将失败。
请考虑以下示例。 在第一个示例中,我们将在初始化时明确定义外键。 在第二个例子中,我们将使用外键追逐,它不假设两个表之间的任何先前关系。
Example 1 − Define foreign key on initialization
q)sector:([sym:`SAMSUNG`HSBC`JPMC`APPLE]ex:`N`CME`DAQ`N;MC:1000 2000 3000 4000)
q)tab:([]sym:`sector$`HSBC`APPLE`APPLE`APPLE`HSBC`JPMC;price:6?9f)
q)show meta tab
c | t f a
------ | ----------
sym | s sector
price | f
q)show select from tab where sym.ex=`N
sym price
----------------
APPLE 4.65382
APPLE 4.643817
APPLE 3.659978
Example 2 − no pre-defined relationship between tables
sector: ([symb:`IBM`MSFT`HSBC]ex:`N`CME`N;MC:1000 2000 3000)
tab:([]sym:`IBM`MSFT`MSFT`HSBC`HSBC;price:5?9f)
要使用外键追逐,我们必须创建一个表来键入扇区。
q)show update mc:(sector([]symb:sym))[`MC] from tab
sym price mc
--------------------------
IBM 7.065297 1000
MSFT 4.812387 2000
MSFT 6.400545 2000
HSBC 3.704373 3000
HSBC 4.438651 3000
预定义外键的常规表示法 -
从c where a is the foreign key (sym), b is a选择ab, where a is the foreign key (sym), b is a
field in the primary key table (ind), c is the
foreign key table (trade)
操纵表
让我们创建一个交易表并检查不同表表达式的结果 -
q)trade:([]sym:5?`ibm`msft`hsbc`samsung;price:5?(303.00*3+1);size:5?(900*5);time:5?(.z.T-365))
q)trade
sym price size time
-----------------------------------------
msft 743.8592 3162 02:32:17.036
msft 641.7307 2917 01:44:56.936
hsbc 838.2311 1492 00:25:23.210
samsung 278.3498 1983 00:29:38.945
ibm 838.6471 4006 07:24:26.842
现在让我们看一下使用q语言操作表的语句。
Select
使用Select语句的语法如下 -
select [columns] [by columns] from table [where clause]
现在让我们举个例子来演示如何使用Select语句 -
q)/ select expression example
q)select sym,price,size by time from trade where size > 2000
time | sym price size
------------- | -----------------------
01:44:56.936 | msft 641.7307 2917
02:32:17.036 | msft 743.8592 3162
07:24:26.842 | ibm 838.6471 4006
Insert
使用Insert语句的语法如下 -
`tablename insert (values)
Insert[`tablename; values]
现在让我们举个例子来演示如何使用Insert语句 -
q)/ Insert expression example
q)`trade insert (`hsbc`apple;302.0 730.40;3020 3012;09:30:17.00409:15:00.000)
5 6
q)trade
sym price size time
------------------------------------------
msft 743.8592 3162 02:32:17.036
msft 641.7307 2917 01:44:56.936
hsbc 838.2311 1492 00:25:23.210
samsung 278.3498 1983 00:29:38.945
ibm 838.6471 4006 07:24:26.842
hsbc 302 3020 09:30:17.004
apple 730.4 3012 09:15:00.000
q)/Insert another value
q)insert[`trade;(`samsung;302.0; 3333;10:30:00.000]
']
q)insert[`trade;(`samsung;302.0; 3333;10:30:00.000)]
,7
q)trade
sym price size time
----------------------------------------
msft 743.8592 3162 02:32:17.036
msft 641.7307 2917 01:44:56.936
hsbc 838.2311 1492 00:25:23.210
samsung 278.3498 1983 00:29:38.945
ibm 838.6471 4006 07:24:26.842
hsbc 302 3020 09:30:17.004
apple 730.4 3012 09:15:00.000
samsung 302 3333 10:30:00.000
删除 (Delete)
使用Delete语句的语法如下 -
delete columns from table
delete from table where clause
现在让我们举个例子来演示如何使用Delete语句 -
q)/Delete expression example
q)delete price from trade
sym size time
-------------------------------
msft 3162 02:32:17.036
msft 2917 01:44:56.936
hsbc 1492 00:25:23.210
samsung 1983 00:29:38.945
ibm 4006 07:24:26.842
hsbc 3020 09:30:17.004
apple 3012 09:15:00.000
samsung 3333 10:30:00.000
q)delete from trade where price > 3000
sym price size time
-------------------------------------------
msft 743.8592 3162 02:32:17.036
msft 641.7307 2917 01:44:56.936
hsbc 838.2311 1492 00:25:23.210
samsung 278.3498 1983 00:29:38.945
ibm 838.6471 4006 07:24:26.842
hsbc 302 3020 09:30:17.004
apple 730.4 3012 09:15:00.000
samsung 302 3333 10:30:00.000
q)delete from trade where price > 500
sym price size time
-----------------------------------------
samsung 278.3498 1983 00:29:38.945
hsbc 302 3020 09:30:17.004
samsung 302 3333 10:30:00.000
更新 (Update)
使用Update语句的语法如下 -
update column: newValue from table where ….
使用以下语法使用强制转换函数更新列的格式/数据类型 -
update column:newValue from `table where …
现在让我们举个例子来演示如何使用Update语句 -
q)/Update expression example
q)update size:9000 from trade where price > 600
sym price size time
------------------------------------------
msft 743.8592 9000 02:32:17.036
msft 641.7307 9000 01:44:56.936
hsbc 838.2311 9000 00:25:23.210
samsung 278.3498 1983 00:29:38.945
ibm 838.6471 9000 07:24:26.842
hsbc 302 3020 09:30:17.004
apple 730.4 9000 09:15:00.000
samsung 302 3333 10:30:00.000
q)/Update the datatype of a column using the cast function
q)meta trade
c | t f a
----- | --------
sym | s
price| f
size | j
time | t
q)update size:`float$size from trade
sym price size time
------------------------------------------
msft 743.8592 3162 02:32:17.036
msft 641.7307 2917 01:44:56.936
hsbc 838.2311 1492 00:25:23.210
samsung 278.3498 1983 00:29:38.945
ibm 838.6471 4006 07:24:26.842
hsbc 302 3020 09:30:17.004
apple 730.4 3012 09:15:00.000
samsung 302 3333 10:30:00.000
q)/ Above statement will not update the size column datatype permanently
q)meta trade
c | t f a
------ | --------
sym | s
price | f
size | j
time | t
q)/to make changes in the trade table permanently, we have do
q)update size:`float$size from `trade
`trade
q)meta trade
c | t f a
------ | --------
sym | s
price | f
size | f
time | t
Q Language - Verb & Adverbs
Kdb +有名词,动词和副词。 所有数据对象和函数都是nouns 。 Verbs通过减少表达式中的方括号和括号的数量来增强可读性。 Adverbs修改二元(2个参数)函数和动词以产生新的相关动词。 副词derived functions称为derived functions或derived verbs 。
Each
each副词用(`)表示,修改二元函数和动词以应用于列表项而不是列表本身。 看看下面的例子 -
q)1, (2 3 5) /Join
1 2 3 5
q)1, '( 2 3 4) /Join each
1 2
1 3
1 4
对于使用关键字“each”的monadic函数,有一种形式。 例如,
q)reverse ( 1 2 3; "abc") /Reverse
a b c
1 2 3
q)each [reverse] (1 2 3; "abc") /Reverse-Each
3 2 1
c b a
q)'[reverse] ( 1 2 3; "abc")
3 2 1
c b a
每个左,右 - 右
每个二元函数有两种变体,分别叫做Each-Left (\ :)和Each-Right (/ :)。 以下示例说明了如何使用它们。
q)x: 9 18 27 36
q)y:10 20 30 40
q)x,y /join
9 18 27 36 10 20 30 40
q)x,'y /each
9 10
18 20
27 30
36 40
q)x: 9 18 27 36
q)y:10 20 30 40
q)x,y /join
9 18 27 36 10 20 30 40
q)x,'y /each, will return a list of pairs
9 10
18 20
27 30
36 40
q)x, \:y /each left, returns a list of each element
/from x with all of y
9 10 20 30 40
18 10 20 30 40
27 10 20 30 40
36 10 20 30 40
q)x,/:y /each right, returns a list of all the x with
/each element of y
9 18 27 36 10
9 18 27 36 20
9 18 27 36 30
9 18 27 36 40
q)1 _x /drop the first element
18 27 36
q)-2_y /drop the last two element
10 20
q) /Combine each left and each right to be a
/cross-product (cartesian product)
q)x,/:\:y
9 10 9 20 9 30 9 40
18 10 18 20 18 30 18 40
27 10 27 20 27 30 27 40
36 10 36 20 36 30 36 40
Q Language - Joins
在q语言中,我们根据提供的输入表和我们想要的连接表的类型提供不同类型的连接。 连接组合来自两个表的数据。 除了外键追逐,还有其他四种方式可以连接表格 -
- Simple join
- Asof join
- Left join
- Union join
在本章中,我们将详细讨论这些连接中的每一个。
简单加入
简单连接是最基本的连接类型,使用逗号','执行。 在这种情况下,两个表必须符合type conformant ,即两个表具有相同顺序的列数和相同的键。
table1,:table2/table1 is assigned the value of table2
对于具有相同长度的表,我们可以使用逗号 - 每个连接来横向连接。 其中一个表可以在这里键入,
Table1, `Table2
Asof Join (aj)
它是最强大的连接,用于在另一个表中获取一个表中字段的值。 一般来说,它用于获得每笔交易时的现行买入价和卖出价。
一般格式
aj[joinColumns;tbl1;tbl2]
例如,
aj[`sym`time;trade;quote]
例子 (Example)
q)tab1:([]a:(1 2 3 4);b:(2 3 4 5);d:(6 7 8 9))
q)tab2:([]a:(2 3 4);b:(3 4 5); c:( 4 5 6))
q)show aj[`a`b;tab1;tab2]
a b d c
-------------
1 2 6
2 3 7 4
3 4 8 5
4 5 9 6
Left Join(lj)
这是aj的一个特例,其中第二个参数是键控表,第一个参数包含右参数键的列。
一般格式
table1 lj Keyed-table
例子 (Example)
q)/Left join- syntax table1 lj table2 or lj[table1;table2]
q)tab1:([]a:(1 2 3 4);b:(2 3 4 5);d:(6 7 8 9))
q)tab2:([a:(2 3 4);b:(3 4 5)]; c:( 4 5 6))
q)show lj[tab1;tab2]
a b d c
-------------
1 2 6
2 3 7 4
3 4 8 5
4 5 9 6
Union Join (uj)
它允许创建具有不同模式的两个表的并集。 它基本上是简单连接的扩展(,)
q)tab1:([]a:(1 2 3 4);b:(2 3 4 5);d:(6 7 8 9))
q)tab2:([]a:(2 3 4);b:(3 4 5); c:( 4 5 6))
q)show uj[tab1;tab2]
a b d c
------------
1 2 6
2 3 7
3 4 8
4 5 9
2 3 4
3 4 5
4 5 6
如果在键控表上使用uj,则主键必须匹配。
Q Language - 函数
类型的函数 (Types of Functions)
功能可以以多种方式分类。 在这里,我们根据它们采用的参数的数量和类型以及结果类型对它们进行了分类。 功能可以,
Atomic - 参数是原子的并产生原子结果
Aggregate - 列表中的原子
Uniform (list from list) - 扩展原子的概念,因为它们适用于列表。 参数列表的计数等于结果列表的计数。
Other - 如果该功能不是来自上述类别。
数学中的二元运算在q中称为dyadic functions ; 例如,“+”。 类似地,一元操作称为monadic functions ; 例如,“abs”或“floor”。
常用函数 (Frequently Used Functions)
在q编程中经常使用很多函数。 在这一节中,我们将看到一些流行功能的用法 -
abs
q) abs -9.9/Absolute value, Negates -ve number & leaves non -ve number
9.9
all
q) all 4 5 0 -4/Logical AND (numeric min), returns the minimum value
0b
最大(&),最小(|)和不(!)
q) /And, Or, and Logical Negation
q) 1b & 1b /And (Max)
1b
q) 1b|0b /Or (Min)
1b
q) not 1b /Logical Negate (Not)
0b
asc
q)asc 1 3 5 7 -2 0 4 /Order list ascending, sorted list
/in ascending order i
s returned
`s#-2 0 1 3 4 5 7
q)/attr - gives the attributes of data, which describe how it's sorted.
`s denotes fully sorted, `u denotes unique and `p and `g are used to
refer to lists with repetition, with `p standing for parted and `g for grouped
avg
q)avg 3 4 5 6 7 /Return average of a list of numeric values
5f
q)/Create on trade table
q)trade:([]time:3?(.z.Z-200);sym:3?(`ibm`msft`apple);price:3?99.0;size:3?100)
by
q)/ by - Groups rows in a table at given sym
q)select sum price by sym from trade /find total price for each sym
sym | price
------ | --------
apple | 140.2165
ibm | 16.11385
cols
q)cols trade/Lists columns of a table
`time`sym`price`size
计数
q)count (til 9)/Count list, count the elements in a list and
/return a single int value 9
port
q)\p 9999/assign port number
q)/csv - This command allows queries in a browser to be exported to
excel by prefixing the query, such as http://localhost:9999/.csv?select from trade where sym =`ibm
cut
q)/ cut - Allows a table or list to be cut at a certain point
q)(1 3 5) cut "abcdefghijkl"
/the argument is split at 1st, 3rd and 5th letter.
"bc"
"de"
"fghijkl"
q)5 cut "abcdefghijkl" /cut the right arg. Into 5 letters part
/until its end.
"abcde"
"fghij"
"kl"
删除 (Delete)
q)/delete - Delete rows/columns from a table
q)delete price from trade
time sym size
---------------------------------------
2009.06.18T06:04:42.919 apple 36
2009.11.14T12:42:34.653 ibm 12
2009.12.27T17:02:11.518 apple 97
Distinct
q)/distinct - Returns the distinct element of a list
q)distinct 1 2 3 2 3 4 5 2 1 3 /generate unique set of number
1 2 3 4 5
enlist
q)/enlist - Creates one-item list.
q)enlist 37
,37
q)type 37 /-ve type value
-7h
q)type enlist 37 /+ve type value
7h
Fill (^)
q)/fill - used with nulls. There are three functions for processing null values.
The dyadic function named fill replaces null values in the right argument with the atomic left argument.
q)100 ^ 3 4 0N 0N -5
3 4 100 100 -5
q)`Hello^`jack`herry``john`
`jack`herry`Hello`john`Hello
Fills
q)/fills - fills in nulls with the previous not null value.
q)fills 1 0N 2 0N 0N 2 3 0N -5 0N
1 1 2 2 2 2 3 3 -5 -5
First
q)/first - returns the first atom of a list
q)first 1 3 34 5 3
1
Flip
q)/flip - Monadic primitive that applies to lists and associations. It interchange the top two levels of its argument.
q)trade
time sym price size
------------------------------------------------------
2009.06.18T06:04:42.919 apple 72.05742 36
2009.11.14T12:42:34.653 ibm 16.11385 12
2009.12.27T17:02:11.518 apple 68.15909 97
q)flip trade
time | 2009.06.18T06:04:42.919 2009.11.14T12:42:34.653
2009.12.27T17:02:11.518
sym | apple ibm apple
price | 72.05742 16.11385 68.15909
size | 36 12 97
iasc
q)/iasc - Index ascending, return the indices of the ascended sorted list relative to the input list.
q)iasc 5 4 0 3 4 9
2 3 1 4 0 5
Idesc
q)/idesc - Index desceding, return the descended sorted list relative to the input list
q)idesc 0 1 3 4
3 2 1 0
in
q)/in - In a list, dyadic function used to query list (on the right-handside) about their contents.
q)(2 4) in 1 2 3
10b
插入
q)/insert - Insert statement, upload new data into a table.
q)insert[`trade;((.z.Z);`samsung;48.35;99)],3
q)trade
time sym price size
------------------------------------------------------
2009.06.18T06:04:42.919 apple 72.05742 36
2009.11.14T12:42:34.653 ibm 16.11385 12
2009.12.27T17:02:11.518 apple 68.15909 97
2015.04.06T10:03:36.738 samsung 48.35 99
key
q)/key - three different functions i.e. generate +ve integer number, gives content of a directory or key of a table/dictionary.
q)key 9
0 1 2 3 4 5 6 7 8
q)key `:c:
`$RECYCLE.BIN`Config.Msi`Documents and Settings`Drivers`Geojit`hiberfil.sys`I..
lower
q)/lower - Convert to lower case and floor
q)lower ("JoHn";`HERRY`SYM)
"john"
`herry`sym
最大和最小(即|和&)
q)/Max and Min/a|b and a&b
q)9|7
9
q)9&5
5
null
q)/null - return 1b if the atom is a null else 0b from the argument list
q)null 1 3 3 0N
0001b
Peach
q)/peach - Parallel each, allows process across slaves
q)foo peach list1 /function foo applied across the slaves named in list1
'list1
q)foo:{x+27}
q)list1:(0 1 2 3 4)
q)foo peach list1 /function foo applied across the slaves named in list1
27 28 29 30 31
Prev
q)/prev - returns the previous element i.e. pushes list forwards
q)prev 0 1 3 4 5 7
0N 0 1 3 4 5
Random( ?)
q)/random - syntax - n?list, gives random sequences of ints and floats
q)9?5
0 0 4 0 3 2 2 0 1
q)3?9.9
0.2426823 1.674133 3.901671
Raze
q)/raze - Flattn a list of lists, removes a layer of indexing from a list of lists. for instance:
q)raze (( 12 3 4; 30 0);("hello";7 8); 1 3 4)
12 3 4
30 0
"hello"
7 8
1
3
4
read0
q)/read0 - Read in a text file
q)read0 `:c:/q/README.txt /gives the contents of *.txt file
read1
q)/read1 - Read in a q data file
q)read1 `:c:/q/t1
0xff016200630b000500000073796d0074696d6500707269636…
reverse
q)/reverse - Reverse a list
q)reverse 2 30 29 1 3 4
4 3 1 29 30 2
q)reverse "HelloWorld"
"dlroWolleH"
set
q)/set - set value of a variable
q)`x set 9
`x
q)x
9
q)`:c:/q/test12 set trade
`:c:/q/test12
q)get `:c:/q/test12
time sym price size
---------------------------------------------------------
2009.06.18T06:04:42.919 apple 72.05742 36
2009.11.14T12:42:34.653 ibm 16.11385 12
2009.12.27T17:02:11.518 apple 68.15909 97
2015.04.06T10:03:36.738 samsung 48.35 99
2015.04.06T10:03:47.540 samsung 48.35 99
2015.04.06T10:04:44.844 samsung 48.35 99
ssr
q)/ssr - String search and replace, syntax - ssr["string";searchstring;replaced-with]
q)ssr["HelloWorld";"o";"O"]
"HellOWOrld"
串
q)/string - converts to string, converts all types to a string format.
q)string (1 2 3; `abc;"XYZ";0b)
(,"1";,"2";,"3")
"abc"
(,"X";,"Y";,"Z")
,"0"
SV
q)/sv - Scalar from vector, performs different tasks dependent on its arguments.
It evaluates the base representation of numbers, which allows us to calculate the number of seconds in a month or convert a length from feet and inches to centimeters.
q)24 60 60 sv 11 30 49
41449 /number of seconds elapsed in a day at 11:30:49
system
q)/system - allows a system command to be sent,
q)system "dir *.py"
" Volume in drive C is New Volume"
" Volume Serial Number is 8CD2-05B2"
""
" Directory of C:\\Users\\myaccount-raj"
""
"09/14/2014 06:32 PM 22 hello1.py"
" 1 File(s) 22 bytes"
tables
q)/tables - list all tables
q)tables `
`s#`tab1`tab2`trade
Til
q)/til - Enumerate
q)til 5
0 1 2 3 4
trim
q)/trim - Eliminate string spaces
q)trim " John "
"John"
vs
q)/vs - Vector from scaler , produces a vector quantity from a scaler quantity
q)"|" vs "20150204|msft|20.45"
"20150204"
"msft"
"20.45"
xasc
q)/xasc - Order table ascending, allows a table (right-hand argument) to be sorted such that (left-hand argument) is in ascending order
q)`price xasc trade
time sym price size
----------------------------------------------------------
2009.11.14T12:42:34.653 ibm 16.11385 12
2015.04.06T10:03:36.738 samsung 48.35 99
2015.04.06T10:03:47.540 samsung 48.35 99
2015.04.06T10:04:44.844 samsung 48.35 99
2009.12.27T17:02:11.518 apple 68.15909 97
2009.06.18T06:04:42.919 apple 72.05742 36
xcol
q)/xcol - Renames columns of a table
q)`timeNew`symNew xcol trade
timeNew symNew price size
-------------------------------------------------------------
2009.06.18T06:04:42.919 apple 72.05742 36
2009.11.14T12:42:34.653 ibm 16.11385 12
2009.12.27T17:02:11.518 apple 68.15909 97
2015.04.06T10:03:36.738 samsung 48.35 99
2015.04.06T10:03:47.540 samsung 48.35 99
2015.04.06T10:04:44.844 samsung 48.35 99
xcols
q)/xcols - Reorders the columns of a table,
q)`size`price xcols trade
size price time sym
-----------------------------------------------------------
36 72.05742 2009.06.18T06:04:42.919 apple
12 16.11385 2009.11.14T12:42:34.653 ibm
97 68.15909 2009.12.27T17:02:11.518 apple
99 48.35 2015.04.06T10:03:36.738 samsung
99 48.35 2015.04.06T10:03:47.540 samsung
99 48.35 2015.04.06T10:04:44.844 samsung
xdesc
q)/xdesc - Order table descending, allows tables to be sorted such that the left-hand argument is in descending order.
q)`price xdesc trade
time sym price size
-----------------------------------------------------------
2009.06.18T06:04:42.919 apple 72.05742 36
2009.12.27T17:02:11.518 apple 68.15909 97
2015.04.06T10:03:36.738 samsung 48.35 99
2015.04.06T10:03:47.540 samsung 48.35 99
2015.04.06T10:04:44.844 samsung 48.35 99
2009.11.14T12:42:34.653 ibm 16.11385 12
xgroup
q)/xgroup - Creates nested table
q)`x xgroup ([]x:9 18 9 18 27 9 9;y:10 20 10 20 30 40)
'length
q)`x xgroup ([]x:9 18 9 18 27 9 9;y:10 20 10 20 30 40 10)
x | y
---- | -----------
9 | 10 10 40 10
18 | 20 20
27 | ,30
xkey
q)/xkey - Set key on table
q)`sym xkey trade
sym | time price size
--------- | -----------------------------------------------
apple | 2009.06.18T06:04:42.919 72.05742 36
ibm | 2009.11.14T12:42:34.653 16.11385 12
apple | 2009.12.27T17:02:11.518 68.15909 97
samsung | 2015.04.06T10:03:36.738 48.35 99
samsung | 2015.04.06T10:03:47.540 48.35 99
samsung | 2015.04.06T10:04:44.844 48.35 99
System Commands
系统命令控制q环境。 它们具有以下形式 -
\cmd [p] where p may be optional
下面讨论了一些流行的系统命令 -
\a [namespace] - 列出给定命名空间中的表
q)/Tables in default namespace
q)\a
,`trade
q)\a .o /table in .o namespace.
,`TI
\b - 查看依赖项
q)/ views/dependencies
q)a:: x+y /global assingment
q)b:: x+1
q)\b
`s#`a`b
\B - 待定视图/依赖项
q)/ Pending views/dependencies
q)a::x+1 /a depends on x
q)\B /the dependency is pending
'/the dependency is pending
q)\B
`s#`a`b
q)\b
`s#`a`b
q)b
29
q)a
29
q)\B
`symbol$()
\cd - 更改目录
q)/change directory, \cd [name]
q)\cd
"C:\\Users\\myaccount-raj"
q)\cd ../new-account
q)\cd
"C:\\Users\\new-account"
\d - 设置当前命名空间
q)/ sets current namespace \d [namespace]
q)\d /default namespace
'
q)\d .o /change to .o
q.o)\d
`.o
q.o)\d . /return to default
q)key ` /lists namespaces other than .z
`q`Q`h`j`o
q)\d .john /change to non-existent namespace
q.john)\d
`.john
q.john)\d .
q)\d
`.
\l - 从db加载文件或目录
q)/ Load file or directory, \l
q)\l test2.q/loading test2.q which is stored in current path.
ric | date ex openP closeP MCap
----------- | -------------------------------------------------
JPMORGAN | 2008.05.23 SENSEX 18.30185 17.16319 17876
HSBC | 2002.05.21 NIFTY 2.696749 16.58846 26559
JPMORGAN | 2006.09.07 NIFTY 14.15219 20.05624 14557
HSBC | 2010.10.11 SENSEX 7.394497 25.45859 29366
JPMORGAN | 2007.10.02 SENSEX 1.558085 25.61478 20390
ric | date ex openP closeP MCap
---------- | ------------------------------------------------
INFOSYS | 2003.10.30 DOW 21.2342 7.565652 2375
RELIANCE | 2004.08.12 DOW 12.34132 17.68381 4201
SBIN | 2008.02.14 DOW 1.830857 9.006485 15465
INFOSYS | 2009.06.11 HENSENG 19.47664 12.05208 11143
SBIN | 2010.07.05 DOW 18.55637 10.54082 15873
\p - 端口号
q)/ assign port number, \p
q)\p
5001i
q)\p 8888
q)\p
8888i
\\ - 从q控制台退出
\\ - exit
Exit form q.
Q Language - Built-in Functions
q编程语言具有一组丰富而强大的内置函数。 内置函数可以是以下类型 -
String function - 将字符串作为输入并返回一个字符串。
Aggregate function - 将列表作为输入并返回原子。
Uniform function - 获取列表并返回相同计数的列表。
Mathematical function - 获取数字参数并返回数字参数。
Miscellaneous function - 除上述以外的所有功能。
字符串函数 (String Functions)
喜欢 - 模式匹配
q)/like is a dyadic, performs pattern matching, return 1b on success else 0b
q)"John" like "J??n"
1b
q)"John My Name" like "J*"
1b
ltrim - 删除前导空格
q)/ ltrim - monadic ltrim takes string argument, removes leading blanks
q)ltrim " Rick "
"Rick "
rtrim - 删除尾随空白
q)/rtrim - takes string argument, returns the result of removing trailing blanks
q)rtrim " Rick "
" Rick"
ss - 字符串搜索
q)/ss - string search, perform pattern matching, same as "like" but return the indices of the matches of the pattern in source.
q)"Life is beautiful" ss "i"
1 5 13
修剪 - 删除前导和尾随空白
q)/trim - takes string argument, returns the result of removing leading & trailing blanks
q)trim " John "
"John"
数学函数 (Mathematical Functions)
acos - cos的倒数
q)/acos - inverse of cos, for input between -1 and 1, return float between 0 and pi
q)acos 1
0f
q)acos -1
3.141593
q)acos 0
1.570796
cor - 给出相关性
q)/cor - the dyadic takes two numeric lists of same count, returns a correlation between the items of the two arguments
q)27 18 18 9 0 cor 27 36 45 54 63
-0.9707253
交叉 - 笛卡尔积
q)/cross - takes atoms or lists as arguments and returns their Cartesian product
q)9 18 cross `x`y`z
9 `x
9 `y
9 `z
18 `x
18 `y
18 `z
var - 方差
q)/var - monadic, takes a scaler or numeric list and returns a float equal to the mathematical variance of the items
q)var 45
0f
q)var 9 18 27 36
101.25
wavg
q)/wavg - dyadic, takes two numeric lists of the same count and returns the average of the second argument weighted by the first argument.
q)1 2 3 4 wavg 200 300 400 500
400f
聚合函数 (Aggregate Functions)
全部 - 和操作
q)/all - monadic, takes a scaler or list of numeric type and returns the result of & applied across the items.
q)all 0b
0b
q)all 9 18 27 36
1b
q)all 10 20 30
1b
任何 - | 手术
q)/any - monadic, takes scaler or list of numeric type and the return the result of | applied across the items
q)any 20 30 40 50
1b
q)any 20012.02.12 2013.03.11
'20012.02.12
prd - 算术产品
q)/prd - monadic, takes scaler, list, dictionary or table of numeric type and returns the arithmetic product.
q)prd `x`y`z! 10 20 30
6000
q)prd ((1 2; 3 4);(10 20; 30 40))
10 40
90 160
和 - 算术和
q)/sum - monadic, takes a scaler, list,dictionary or table of numeric type and returns the arithmetic sum.
q)sum 2 3 4 5 6
20
q)sum (1 2; 4 5)
5 7
统一函数 (Uniform Functions)
Deltas - 与之前的项目不同。
q)/deltas -takes a scalar, list, dictionary or table and returns the difference of each item from its predecessor.
q)deltas 2 3 5 7 9
2 1 2 2 2
q)deltas `x`y`z!9 18 27
x | 9
y | 9
z | 9
填充 - 填充空值
q)/fills - takes scalar, list, dictionary or table of numeric type and returns a c copy of the source in which non-null items are propagated forward to fill nulls
q)fills 1 0N 2 0N 4
1 1 2 2 4
q)fills `a`b`c`d! 10 0N 30 0N
a | 10
b | 10
c | 30
d | 30
maxs - 累积最大值
q)/maxs - takes scalar, list, dictionary or table and returns the cumulative maximum of the source items.
q)maxs 1 2 4 3 9 13 2
1 2 4 4 9 13 13
q)maxs `a`b`c`d!9 18 0 36
a | 9
b | 18
c | 18
d | 36
其它功能 (Miscellaneous Functions)
计数 - 返回元素的数量
q)/count - returns the number of entities in its argument.
q)count 10 30 30
3
q)count (til 9)
9
q)count ([]a:9 18 27;b:1.1 2.2 3.3)
3
区别 - 返回不同的实体
q)/distinct - monadic, returns the distinct entities in its argument
q)distinct 1 2 3 4 2 3 4 5 6 9
1 2 3 4 5 6 9
除了 - 第二个arg中不存在的元素。
q)/except - takes a simple list (target) as its first argument and returns a list containing the items of target that are not in its second argument
q)1 2 3 4 3 1 except 1
2 3 4 3
fill - 用第一个参数填充null
q)/fill (^) - takes an atom as its first argument and a list(target) as its second argument and return a list obtained by substituting the first argument for every occurrence of null in target
q)42^ 9 18 0N 27 0N 36
9 18 42 27 42 36
q)";"^"Life is Beautiful"
"Life;is;Beautiful"
Q Language - Queries
q中的查询更短更简单,并扩展了sql的功能。 主查询表达式是“选择表达式”,它以最简单的形式提取子表,但也可以创建新列。
Select expression的一般形式如下 -
<b class="notranslate">Select</b> columns <b class="notranslate">by</b> columns <b class="notranslate">from</b> table where conditions
**Note − by & where短语是可选的,只有'from expression'是必需的。
一般来说,语法将是 -
select [a] [by b] from t [where c]
update [a] [by b] from t [where c]
q表达式的语法看起来与SQL非常相似,但q表达式简单而强大。 上述q表达式的等效sql表达式如下 -
select [b] [a] from t [where c] [group by b order by b]
update t set [a] [where c]
所有子句都在列上执行,因此q可以利用顺序。 由于Sql查询不是基于订单,因此无法获得此优势。
与对应的sql相比,关系查询的大小通常要小得多。 有序和功能查询执行sql中很难的事情。
在历史数据库中, where子句的顺序非常重要,因为它会影响查询的性能。 partition变量(日期/月/日)始终首先出现,然后是已排序和索引的列(通常是sym列)。
例如,
select from table where date in d, sym in s
要快得多,
select from table where sym in s, date in d
基础知识查询
让我们在记事本中编写一个查询脚本(如下所示),保存(如* .q),然后加载它。
sym:asc`AIG`CITI`CSCO`IBM`MSFT;
ex:"NASDAQ"
dst:`$":c:/q/test/data/"; /database destination
@[dst;`sym;:;sym];
n:1000000;
trade:([]sym:n?`sym;time:10:30:00.0+til
n;price:n?3.3e;size:n?9;ex:n?ex);
quote:([]sym:n?`sym;time:10:30:00.0+til
n;bid:n?3.3e;ask:n?3.3e;bsize:n?9;asize:n?9;ex:n?ex);
{@[;`sym;`p#]`sym xasc x}each`trade`quote;
d:2014.08.07 2014.08.08 2014.08.09 2014.08.10 2014.08.11; /Date vector can also be changed by the user
dt:{[d;t].[dst;(`$string d;t;`);:;value t]};
d dt/:\:`trade`quote;
Note: Once you run this query, two folders .i.e. "test" and "data" will be created under "c:/q/", and date partition data can be seen inside data folder.
具有约束的查询
* Denotes HDB query
Select all IBM trades
select from trade where sym in `IBM
*Select all IBM trades on a certain day
thisday: 2014.08.11
select from trade where date=thisday,sym=`IBM
Select all IBM trades with a price 》 100
select from trade where sym=`IBM, price > 100.0
Select all IBM trades with a price less than or equal to 100
select from trade where sym=`IBM,not price > 100.0
*Select all IBM trades between 10.30 and 10.40, in the morning, on a certain date
thisday: 2014.08.11
select from trade where
date = thisday, sym = `IBM, time > 10:30:00.000,time < 10:40:00.000
Select all IBM trades in ascending order of price
`price xasc select from trade where sym =`IBM
*Select all IBM trades in descending order of price in a certain time frame
`price xdesc select from trade where date within 2014.08.07 2014.08.11, sym =`IBM
Composite sort − sort ascending order by sym and then sort the result in descending order of price
`sym xasc `price xdesc select from trade where date = 2014.08.07,size = 5
Select all IBM or MSFT trades
select from trade where sym in `IBM`MSFT
*Calculate count of all symbols in ascending order within a certain time frame
`numsym xasc select numsym: count i by sym from trade where date within 2014.08.07 2014.08.11
*Calculate count of all symbols in descending order within a certain time frame
`numsym xdesc select numsym: count i by sym from trade where date within 2014.08.07 2014.08.11
* What is the maximum price of IBM stock within a certain time frame, and when does this first happen?
select time,ask from quote where date within 2014.08.07 2014.08.11,
sym =`IBM, ask = exec first ask from select max ask from quote where
sym =`IBM
Select the last price for each sym in hourly buckets
select last price by hour:time.hh, sym from trade
具有聚合的查询
* Calculate vwap (Volume Weighted Average Price) of all symbols
select vwap:size wavg price by sym from trade
* Count the number of records (in millions) for a certain month
(select trade:1e-6*count i by date.dd from trade where date.month=2014.08m) + select quote:1e-6*count i by date.dd from quote where date.month=2014.08m
* HLOC – Daily High, Low, Open and Close for CSCO in a certain month
select high:max price,low:min price,open:first price,close:last price by date.dd from trade where date.month=2014.08m,sym =`CSCO
* Daily Vwap for CSCO in a certain month
select vwap:size wavg price by date.dd from trade where date.month = 2014.08m ,sym = `CSCO
* Calculate the hourly mean, variance and standard deviation of the price for AIG
select mean:avg price, variance:var price, stdDev:dev price by date, hour:time.hh from trade where sym = `AIG
Select the price range in hourly buckets
select range:max[price] – min price by date,sym,hour:time.hh from trade
* Daily Spread (average bid-ask) for CSCO in a certain month
select spread:avg bid-ask by date.dd from quote where date.month = 2014.08m, sym = `CSCO
* Daily Traded Values for all syms in a certain month
select dtv:sum size by date,sym from trade where date.month = 2014.08m
Extract a 5 minute vwap for CSCO
select size wavg price by 5 xbar time.minute from trade where sym = `CSCO
* Extract 10 minute bars for CSCO
select high:max price,low:min price,close:last price by date, 10 xbar time.minute from trade where sym = `CSCO
* Find the times when the price exceeds 100 basis points (100e-4) over the last price for CSCO for a certain day
select time from trade where date = 2014.08.11,sym = `CSCO,price > 1.01*last price
* Full Day Price and Volume for MSFT in 1 Minute Intervals for the last date in the database
select last price,last size by time.minute from trade where date = last date, sym = `MSFT
Q Language - Inter-Process Communication
KDB +允许一个进程通过进程间通信与另一个进程通信。 Kdb +进程可以连接到同一台计算机,同一网络甚至远程的任何其他kdb +。 我们只需要指定端口,然后客户端就可以与该端口通信。 任何q进程都可以与任何其他q进程通信,只要它可以在网络上访问并且正在侦听连接。
服务器进程侦听连接并处理任何请求
客户端进程启动连接并发送要执行的命令
客户端和服务器可以在同一台机器上,也可以在不同的机器上。 进程可以是客户端和服务器。
沟通可以是,
Synchronous (等待返回结果)
Asynchronous (没有等待,没有返回结果)
初始化服务器
通过指定要侦听的端口来初始化q服务器,
q –p 5001/command line
\p 5001 /session command
沟通处理
通信句柄是以“:”开头并具有以下形式的符号 -
`:[server]:port-number
例子 (Example)
`::5001 /server and client on same machine
`:jack:5001 /server on machine jack
`:192.168.0.156 /server on specific IP address
`:www.myfx.com:5001 /server at <a href="www.myfx.com">www.myfx.com</a>
要启动连接,我们使用函数“hopen”返回一个整数连接句柄。 此句柄用于所有后续客户端请求。 例如 -
q)h:hopen `::5001
q)h"til 5"
0 1 2 3 4
q)hclose h
同步和异步消息
一旦我们有了句柄,我们就可以同步或异步发送消息。
Synchronous Message - 一旦发送消息,它就会等待并返回结果。 其格式如下 -
handle “message”
Asynchronous Message - 发送消息后,立即开始处理下一个语句,而不必等待并返回结果。 其格式如下 -
neg[handle] “message”
需要响应的消息(例如函数调用或select语句)通常使用同步形式; 而不需要返回输出的消息(例如,将更新插入表)将是异步的。
Q Language - Message Handler
当q进程通过进程间通信连接到另一个q进程时,它由消息处理程序处理。 这些消息处理程序具有默认行为。 例如,在同步消息处理的情况下,处理程序返回查询的值。 在这种情况下,同步处理程序是.z.pg ,我们可以根据要求覆盖它。
Kdb +进程有几个预定义的消息处理程序。 消息处理程序对于配置数据库很重要。 一些用法包括 -
Logging - 记录传入消息(有助于发生任何致命错误),
Security - 允许/禁止基于用户名/ IP地址访问数据库,某些函数调用等。 它有助于仅向授权订户提供访问权限。
Handle connections/disconnections其他进程的Handle connections/disconnections 。
预定义的消息处理程序
下面讨论一些预定义的消息处理程序。
.z.pg
它是一个同步消息处理程序(进程获取)。 只要在kdb +实例上收到同步消息,就会自动调用此函数。
参数是要执行的字符串/函数调用,即传递的消息。 默认情况下,它定义如下 -
.z.pg: {value x} /simply execute the message
received but we can overwrite it to
give any customized result.
.z.pg : {handle::.z.w;value x} /this will store the remote handle
.z.pg : {show .z.w;value x} /this will show the remote handle
.z.ps
它是一个异步消息处理程序(进程集)。 它是异步消息的等效处理程序。 参数是要执行的字符串/函数调用。 默认情况下,它定义为,
.z.pg : {value x} /Can be overriden for a customized action.
以下是异步消息的自定义消息处理程序,我们使用了受保护的执行,
.z.pg: {@[value; x; errhandler x]}
这里errhandler是一个在出现任何意外错误时使用的函数。
.z.po[]
它是一个连接打开处理程序(进程打开)。 它在远程进程打开连接时执行。 要在打开与进程的连接时查看句柄,我们可以将.z.po定义为,
.z.po : {Show “Connection opened by” , string h: .z.h}
.z.pc[]
它是一个紧密的连接处理程序(进程关闭)。 连接关闭时调用它。 我们可以创建自己的关闭处理程序,它可以将全局连接句柄重置为0,并发出命令将计时器设置为每3秒(3000毫秒)触发(执行)。
.z.pc : { h::0; value “\\t 3000”}
计时器处理程序(.z.ts)尝试重新打开连接。 成功后,它会关闭计时器。
.z.ts : { h:: hopen `::5001; if [h>0; value “\\t 0”] }
.z.pi[]
PI代表过程输入。 它被称为任何类型的输入。 它可用于处理控制台输入或远程客户端输入。 使用.z.pi [],可以验证控制台输入或替换默认显示。 此外,它还可用于任何类型的日志记录操作。
q).z.pi
'.z.pi
q).z.pi:{">", .Q.s value x}
q)5+4
>9
q)30+42
>72
q)30*2
>60
q)\x .z.pi
>q)
q)5+4
9
.z.pw
它是验证连接处理程序(用户身份验证)。 当向kdb +会话打开连接时,它会添加额外的回调。 它在-u/-U检查之后和.z.po(端口打开)之前调用。
.z.pw : {[user_id;passwd] 1b}
输入是userid (符号)和password (文本)。
Q Language - Attributes
表的列表,词典或列可以应用属性。 属性在列表中强加某些属性。 某些属性可能会在修改时消失。
属性类型
Sorted (`s#)
`s#表示列表按升序排序。 如果列表由asc(或xasc)显式排序,则列表将自动设置已排序的属性。
q)L1: asc 40 30 20 50 9 4
q)L1
`s#4 9 20 30 40 50
已知要排序的列表也可以明确设置属性。 Q将检查列表是否已排序,如果不排序,将抛出s-fail错误。
q)L2:30 40 24 30 2
q)`s#L2
's-fail
排序的属性将在未排序的附加时丢失。
Parted (`p#)
`p#表示列表已分开,相同的项目是连续存储的。
范围是具有基础int值的int或temporal type ,例如年,月,日等。如果符号被枚举,您还可以对符号进行分区。
应用parted属性会创建一个索引字典,将每个唯一的输出值映射到第一次出现的位置。 当列表被分开时,查找要快得多,因为线性搜索被哈希表查找替换。
q)L:`p# 99 88 77 1 2 3
q)L
`p#99 88 77 1 2 3
q)L,:3
q)L
99 88 77 1 2 3 3
Note −
即使操作保留了分区,parted属性也不会在列表上的操作下保留。
当实体数量达到十亿并且大多数分区具有相当大的尺寸时,应该考虑分开的属性,即,存在显着的重复。
Grouped (`g#)
`g#表示列表已分组。 构建并维护内部字典,将每个唯一项映射到其每个索引,这需要相当大的存储空间。 对于包含大小为s唯一项的长度L的列表,这将是(L × 4) + (u × s)个字节。
当没有关于其结构的其他假设时,可以将分组应用于列表。
该属性可以应用于任何类型的列表。 它保留在追加上,但在删除时丢失。
q)L: `g# 1 2 3 4 5 4 2 3 1 4 5 6
q)L
`g#1 2 3 4 5 4 2 3 1 4 5 6
q)L,:9
q)L
`g#1 2 3 4 5 4 2 3 1 4 5 6 9
q)L _:2
q)L
1 2 4 5 4 2 3 1 4 5 6 9
Unique (`#u)
将唯一属性(`u#)应用于列表表示列表中的项是不同的。 知道列表的元素是唯一的,可以大大加快速度,并允许q尽早执行一些比较。
当列表标记为唯一时,将为列表中的每个项创建内部哈希映射。 列表上的操作必须保持唯一性或属性丢失。
q)LU:`u#`MSFT`SAMSUNG`APPLE
q)LU
`u#`MSFT`SAMSUNG`APPLE
q)LU,:`IBM /Uniqueness preserved
q)LU
`u#`MSFT`SAMSUNG`APPLE`IBM
q)LU,:`SAMSUNG /Attribute lost
q)LU
`MSFT`SAMSUNG`APPLE`IBM`SAMSUNG
Note −
`u#保留在连接上,保留了唯一性。 它在删除和非唯一连接时丢失。
搜索`u#列表是通过哈希函数完成的。
删除属性
可以通过应用`#来删除属性。
应用属性
应用属性的三种格式是 -
L: `s# 14 2 3 3 9 /在列表创建期间指定
@[ `.; `L ; `s#] @[ `.; `L ; `s#] /功能适用,即变量列表L.
/在默认命名空间(即`。)中
/排序的`s#属性
Update `s#time from `tab
/更新表(tab)以应用
/属性。
让我们将上述三种不同的格式应用于示例。
q)/ set the attribute during creation
q)L:`s# 3 4 9 10 23 84 90
q)/apply the attribute to existing list data
q)L1: 9 18 27 36 42 54
q)@[`.;`L1;`s#]
`.
q)L1 /check
`s#9 18 27 36 42 54
q)@[`.;`L1;`#] /clear attribute
`.
q)L1
9 18 27 36 42 54
q)/update a table to apply the attribute
q)t: ([] sym:`ibm`msft`samsung; mcap:9000 18000 27000)
q)t:([]time:09:00 09:30 10:00t;sym:`ibm`msft`samsung; mcap:9000 18000 27000)
q)t
time sym mcap
---------------------------------
09:00:00.000 ibm 9000
09:30:00.000 msft 18000
10:00:00.000 samsung 27000
q)update `s#time from `t
`t
q)meta t /check it was applied
c | t f a
------ | -----
time | t s
sym | s
mcap | j
Above we can see that the attribute column in meta table results shows the time column is sorted (`s#).
Q Language - Functional Queries
功能(动态)查询允许将列名指定为典型q-sql select/exec/delete列的符号。 当我们想要动态指定列名时,它非常方便。
功能形式是 -
?[t;c;b;a] /for select
![t;c;b;a] /for update
哪里
t是一张桌子;
a是聚合词典;
b短语; 和
c是约束列表。
注意 -
a , b和c中a所有q实体必须通过名称引用,即包含实体名称的符号。
select解释器的句法形式由q解释器解析为它们的等效函数形式,因此两种形式之间没有性能差异。
功能选择
以下代码块显示了如何使用functional select -
q)t:([]n:`ibm`msft`samsung`apple;p:40 38 45 54)
q)t
n p
-------------------
ibm 40
msft 38
samsung 45
apple 54
q)select m:max p,s:sum p by name:n from t where p>36, n in `ibm`msft`apple
name | m s
------ | ---------
apple | 54 54
ibm | 40 40
msft | 38 38
例子1 (Example 1)
让我们从最简单的情况开始, “select from t”的功能版本看起来像 -
q)?[t;();0b;()] /select from t
n p
-----------------
ibm 40
msft 38
samsung 45
apple 54
例子2 (Example 2)
在以下示例中,我们使用enlist函数创建单例以确保适当的实体是列表。
q)wherecon: enlist (>;`p;40)
q)?[`t;wherecon;0b;()]/select from t where p > 40
n p
----------------
samsung 45
apple 54
例子3 (Example 3)
q)groupby: enlist[`p] ! enlist `p
q)selcols: enlist [`n]!enlist `n
q)?[ `t;(); groupby;selcols] /select n by p from t
p | n
----- | -------
38 | msft
40 | ibm
45 | samsung
54 | apple
功能执行
exec的功能形式是select的简化形式。
q)?[t;();();`n] /exec n from t (functional form of exec)
`ibm`msft`samsung`apple
q)?[t;();`n;`p] /exec p by n from t (functional exec)
apple | 54
ibm | 40
msft | 38
samsung | 45
功能更新
更新的功能形式完全类似于select的功能形式。 在以下示例中,使用enlist是为了创建单例,以确保输入实体是列表。
q)c:enlist (>;`p;0)
q)b: (enlist `n)!enlist `n
q)a: (enlist `p) ! enlist (max;`p)
q)![t;c;b;a]
n p
-------------
ibm 40
msft 38
samsung 45
apple 54
功能删除
功能删除是功能更新的简化形式。 其语法如下 -
![t;c;0b;a] /t is a table, c is a list of where constraints, a is a
/list of column names
现在让我们举一个例子来说明功能删除是如何工作的 -
q)![t; enlist (=;`p; 40); 0b;`symbol$()]
/delete from t where p = 40
n p
---------------
msft 38
samsung 45
apple 54
Q Language - Table Arithmetic
在本章中,我们将学习如何操作字典和表格。 让我们从词典开始 -
q)d:`u`v`x`y`z! 9 18 27 36 45 /Creating a dictionary d
q)/ key of this dictionary (d) is given by
q)key d
`u`v`x`y`z
q)/and the value by
q)value d
9 18 27 36 45
q)/a specific value
q)d`x
27
q)d[`x]
27
q)/values can be manipulated by using the arithmetic operator +-*% as,
q)45 + d[`x`y]
72 81
如果需要修改字典值,那么修改公式可以是 -
q)@[`d;`z;*;9]
`d
q)d
u | 9
v | 18
x | 27
y | 36
q)/Example, table tab
q)tab:([]sym:`;time:0#0nt;price:0n;size:0N)
q)n:10;sym:`IBM`SAMSUNG`APPLE`MSFT
q)insert[`tab;(n?sym;("t"$.z.Z);n?100.0;n?100)]
0 1 2 3 4 5 6 7 8 9
q)`time xasc `tab
`tab
q)/ to get particular column from table tab
q)tab[`size]
12 10 1 90 73 90 43 90 84 63
q)tab[`size]+9
21 19 10 99 82 99 52 99 93 72
z | 405
q)/Example table tab
q)tab:([]sym:`;time:0#0nt;price:0n;size:0N)
q)n:10;sym:`IBM`SAMSUNG`APPLE`MSFT
q)insert[`tab;(n?sym;("t"$.z.Z);n?100.0;n?100)]
0 1 2 3 4 5 6 7 8 9
q)`time xasc `tab
`tab
q)/ to get particular column from table tab
q)tab[`size]
12 10 1 90 73 90 43 90 84 63
q)tab[`size]+9
21 19 10 99 82 99 52 99 93 72
q)/Example table tab
q)tab:([]sym:`;time:0#0nt;price:0n;size:0N)
q)n:10;sym:`IBM`SAMSUNG`APPLE`MSFT
q)insert[`tab;(n?sym;("t"$.z.Z);n?100.0;n?100)]
0 1 2 3 4 5 6 7 8 9
q)`time xasc `tab
`tab
q)/ to get particular column from table tab
q)tab[`size]
12 10 1 90 73 90 43 90 84 63
q)tab[`size]+9
21 19 10 99 82 99 52 99 93 72
q)/We can also use the @ amend too
q)@[tab;`price;-;2]
sym time price size
--------------------------------------------
APPLE 11:16:39.779 6.388858 12
MSFT 11:16:39.779 17.59907 10
IBM 11:16:39.779 35.5638 1
SAMSUNG 11:16:39.779 59.37452 90
APPLE 11:16:39.779 50.94808 73
SAMSUNG 11:16:39.779 67.16099 90
APPLE 11:16:39.779 20.96615 43
SAMSUNG 11:16:39.779 67.19531 90
IBM 11:16:39.779 45.07883 84
IBM 11:16:39.779 61.46716 63
q)/if the table is keyed
q)tab1:`sym xkey tab[0 1 2 3 4]
q)tab1
sym | time price size
--------- | ----------------------------------
APPLE | 11:16:39.779 8.388858 12
MSFT | 11:16:39.779 19.59907 10
IBM | 11:16:39.779 37.5638 1
SAMSUNG | 11:16:39.779 61.37452 90
APPLE | 11:16:39.779 52.94808 73
q)/To work on specific column, try this
q){tab1[x]`size} each sym
1 90 12 10
q)(0!tab1)`size
12 10 1 90 73
q)/once we got unkeyed table, manipulation is easy
q)2+ (0!tab1)`size
14 12 3 92 75
Q Language - Tables on Disk
硬盘上的数据(也称为历史数据库)可以保存为三种不同的格式 - 平面文件,显示表和分区表。 在这里,我们将学习如何使用这三种格式来保存数据。
平面文件
平面文件完全加载到内存中,这就是它们的大小(内存占用)应该很小的原因。 表完全保存在磁盘上的一个文件中(因此大小很重要)。
用于操作这些表的函数是set/get -
`:path_to_file/filename set tablename
让我们举一个例子来说明它是如何工作的 -
q)tables `.
`s#`t`tab`tab1
q)`:c:/q/w32/tab1_test set tab1
`:c:/q/w32/tab1_test
在Windows环境中,平面文件保存在位置 - C:\q\w32
从磁盘(历史数据库)获取平面文件并使用get命令,如下所示 -
q)tab2: get `:c:/q/w32/tab1_test
q)tab2
sym | time price size
--------- | -------------------------------
APPLE | 11:16:39.779 8.388858 12
MSFT | 11:16:39.779 19.59907 10
IBM | 11:16:39.779 37.5638 1
SAMSUNG | 11:16:39.779 61.37452 90
APPLE | 11:16:39.779 52.94808 73
创建一个新表tab2 ,其内容存储在tab1_test文件中。
播放表格
如果表中的列太多,那么我们以splayed格式存储这些表,即我们将它们保存在目录中的磁盘上。 在目录内,每个列都保存在一个单独的文件中,名称与列名相同。 每列都保存为kdb +二进制文件中相应类型的列表。
当我们必须频繁访问其多列中的几列时,以splayed格式保存表非常有用。 一个splayed表目录包含.d二进制文件,其中包含列的顺序。
与平面文件非常相似,可以使用set命令将表保存为splayed。 要将表保存为splayed,文件路径应以反向结束 -
`:path_to_filename/filename/ set tablename
对于读取展开的表,我们可以使用get函数 -
tablename: get `:path_to_file/filename
Note - 对于要保存为展开的表,应该取消键控和枚举。
在Windows环境中,您的文件结构将如下所示 -
分区表
分区表提供了一种管理包含大量数据的大型表的有效方法。 分区表是分布在更多分区(目录)上的splayed表。
在每个分区内,一个表将拥有自己的目录,其中包含一个splayed表的结构。 这些表可以按日/月/年分开,以便提供对其内容的优化访问。
要获取分区表的内容,请使用以下代码块 -
q)get `:c:/q/data/2000.01.13 // <b class="notranslate">“get”</b> command used, sample folder
quote| +`sym`time`bid`ask`bsize`asize`ex!(`p#`sym!0 0 0 0 0 0 0 0 0 0 0
0 0 0….
trade| +`sym`time`price`size`ex!(`p#`sym!0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 ….
让我们试着获取交易表的内容 -
q)get `:c:/q/data/2000.01.13/trade
sym time price size ex
--------------------------------------------------
0 09:30:00.496 0.4092016 7 T
0 09:30:00.501 1.428629 4 N
0 09:30:00.707 0.5647834 6 T
0 09:30:00.781 1.590509 5 T
0 09:30:00.848 2.242627 3 A
0 09:30:00.860 2.277041 8 T
0 09:30:00.931 0.8044885 8 A
0 09:30:01.197 1.344031 2 A
0 09:30:01.337 1.875 3 A
0 09:30:01.399 2.187723 7 A
Note - 分区模式适用于每天有数百万条记录的表(即时间序列数据)
Sym文件
sym文件是一个kdb +二进制文件,包含所有splayed和分区表中的符号列表。 它可以阅读,
get `:sym
par.txt file (optional)
这是一个配置文件,在分区分布在多个目录/磁盘驱动器上时使用,并包含磁盘分区的路径。
Q Language - Maintenance Functions
.Q.en
.Q.en是一个二元函数,它通过枚举符号列来帮助扩展表。 当我们处理历史数据库(splayed,分区表等)时,它尤其有用。 -
.Q.en[`:directory;table]
其中directory是sym file所在的历史数据库的主目录, table是要枚举的表。
手动枚举表不需要将它们保存为splayed表,因为这将通过 -
.Q.en[`:directory_where_symbol_file_stored]table_name
.Q.dpft
.Q.dpft函数有助于创建分区和分段表。 它是.Q.en高级形式,因为它不仅会.Q.en表,还会创建分区表。
.Q.dpft使用了四个参数 -
我们要创建分区的数据库的符号文件句柄,
q我们将用于对表进行分区的数据值,
将要应用parted(`p#)属性的字段的名称(通常是`sym),和
表名。
让我们举个例子看看它是如何工作的 -
q)tab:([]sym:5?`msft`hsbc`samsung`ibm;time:5?(09:30:30);price:5?30.25)
q).Q.dpft[`:c:/q/;2014.08.24;`sym;`tab]
`tab
q)delete tab from `
'type
q)delete tab from `/
'type
q)delete tab from .
'type
q)delete tab from `.
`.
q)tab
'tab
我们已从内存中删除了表格tab 。 现在让我们从db加载它
q)\l c:/q/2014.08.24/
q)\a
,`tab
q)tab
sym time price
-------------------------------
hsbc 07:38:13 15.64201
hsbc 07:21:05 5.387037
msft 06:16:58 11.88076
msft 08:09:26 12.30159
samsung 04:57:56 15.60838
.Q.chk
.Q.chk是一个monadic函数,其单个参数是根目录的符号文件句柄。 它通过检查根中的每个分区子目录,在必要时在分区中创建空表。
.Q.chk `:directory
其中directory是历史数据库的主目录。