序列化外键表在kdb内部的工作原理
我有一个键控表(引用表),使用外键链接到引用表,并使用set运算符序列化这两个表序列化外键表在kdb内部的工作原理,kdb,Kdb,我有一个键控表(引用表),使用外键链接到引用表,并使用set运算符序列化这两个表 q)kt:([sym:`GOOG`AMZN`FB]; px:20 30 40); q)`:/Users/uts/db/kt set kt q)t:([] sym:`kt$5?`GOOG`AMZN`FB; vol:5?10000) q)`:/Users/uts/db/t set t 然后我从内存中删除这些表 q)delete kt,t from `. 现在我反序列化内存中的表t: t:get `:/Users/u
q)kt:([sym:`GOOG`AMZN`FB]; px:20 30 40);
q)`:/Users/uts/db/kt set kt
q)t:([] sym:`kt$5?`GOOG`AMZN`FB; vol:5?10000)
q)`:/Users/uts/db/t set t
然后我从内存中删除这些表
q)delete kt,t from `.
现在我反序列化内存中的表t:
t:get `:/Users/uts/db/t
如果在此之后执行metat
,则会失败,期望kt作为外键。
如果我按预期打印t,它会在表t的sym列中显示索引值
因此,问题出现了:
-rw-r--r--1 uts员工100 4月13日23:09 t
tl;dr外键存储为引用表的键列的4字节索引加上外键引用表的名称的向量 据我所知,kx从未记录过它们的文件格式,但我认为一些与您的问题相关的有用信息可以从q控制台会话中推断出来 让我稍微修改一下您的示例,使事情更简单
q)show kt:([sym:`GOOG`AMZN`FB]; px:20 30 40)
sym | px
----| --
GOOG| 20
AMZN| 30
FB | 40
q)show t:([] sym:`kt$`GOOG`GOOG`AMZN`FB`FB)
sym
----
GOOG
GOOG
AMZN
FB
FB
我只在t
中留下了一列-sym
,因为vol
与问题无关。让我们先在没有任何数据的情况下保存t
:
现在我们知道,当它为空时,表示t
需要30个字节。让我们看看当我们开始向t
添加行时是否有一种模式:
q){`:/tmp/t set x#t;`cnt`size!(x;hcount[`:/tmp/t] - 30)} each til[11], 100 1000 1000000
cnt size
---------------
0 0
1 4
2 8
3 12
4 16
5 20
6 24
7 28
8 32
9 36
10 40
100 400
1000 4000
1000000 4000000
我们可以看到,添加一行会将t
的大小增加四个字节。这4个字节是什么?它们能代表符号本身吗?不,因为如果是,并且我们在kt
中重命名了sym
值,则会影响磁盘上t
的大小,但不会:
q)update sym:`$50#.Q.a from `kt where sym=`GOOG
`kt
q)1#t
sym
--------------------------------------------------
abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwx
q)`:/tmp/t set 1#t
`:/tmp/t
q)hcount `:/tmp/t
34
还是34字节。我认为现在应该很明显,4字节是一个索引,但是索引是什么?它是一个列的索引,必须准确地称为sym
?显然不是
q)kt:`foo xcol kt
q)t
sym
--------------------------------------------------
abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwx
abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwx
AMZN
FB
FB
在kt
中不再有名为sym
的列,但是t
一点也没有改变!我们可以更进一步,在kt
中更改foo
(例如sym
)的类型:
q)update foo:-1 -2 -3.0 from `kt
`kt
q)t
sym
---
-1
-1
-2
-3
-3
它不仅改变了t
,还改变了它的元数据:
q)meta t
c | t f a
---| ------
sym| f kt
q)/ ^------- used to be s
我希望现在已经很清楚了,kdb存储了引用表的键列的4字节索引和表名(但不是键列名!)。如果引用的表丢失,kdb将无法重建原始数据并显示裸索引。需要通过导线发送参考表,然后用实际值替换索引,以便接收方可以看到实际数据。tl;dr外键存储为引用表的键列的4字节索引加上外键引用表的名称的向量 据我所知,kx从未记录过它们的文件格式,但我认为一些与您的问题相关的有用信息可以从q控制台会话中推断出来 让我稍微修改一下您的示例,使事情更简单
q)show kt:([sym:`GOOG`AMZN`FB]; px:20 30 40)
sym | px
----| --
GOOG| 20
AMZN| 30
FB | 40
q)show t:([] sym:`kt$`GOOG`GOOG`AMZN`FB`FB)
sym
----
GOOG
GOOG
AMZN
FB
FB
我只在t
中留下了一列-sym
,因为vol
与问题无关。让我们先在没有任何数据的情况下保存t
:
现在我们知道,当它为空时,表示t
需要30个字节。让我们看看当我们开始向t
添加行时是否有一种模式:
q){`:/tmp/t set x#t;`cnt`size!(x;hcount[`:/tmp/t] - 30)} each til[11], 100 1000 1000000
cnt size
---------------
0 0
1 4
2 8
3 12
4 16
5 20
6 24
7 28
8 32
9 36
10 40
100 400
1000 4000
1000000 4000000
我们可以看到,添加一行会将t
的大小增加四个字节。这4个字节是什么?它们能代表符号本身吗?不,因为如果是,并且我们在kt
中重命名了sym
值,则会影响磁盘上t
的大小,但不会:
q)update sym:`$50#.Q.a from `kt where sym=`GOOG
`kt
q)1#t
sym
--------------------------------------------------
abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwx
q)`:/tmp/t set 1#t
`:/tmp/t
q)hcount `:/tmp/t
34
还是34字节。我认为现在应该很明显,4字节是一个索引,但是索引是什么?它是一个列的索引,必须准确地称为sym
?显然不是
q)kt:`foo xcol kt
q)t
sym
--------------------------------------------------
abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwx
abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwx
AMZN
FB
FB
在kt
中不再有名为sym
的列,但是t
一点也没有改变!我们可以更进一步,在kt
中更改foo
(例如sym
)的类型:
q)update foo:-1 -2 -3.0 from `kt
`kt
q)t
sym
---
-1
-1
-2
-3
-3
它不仅改变了t
,还改变了它的元数据:
q)meta t
c | t f a
---| ------
sym| f kt
q)/ ^------- used to be s
我希望现在已经很清楚了,kdb存储了引用表的键列的4字节索引和表名(但不是键列名!)。如果引用的表丢失,kdb将无法重建原始数据并显示裸索引。如果需要通过导线发送参考表,则用实际值替换索引,以便接收方可以看到实际数据