在 kdb 中更新磁盘上的序列化表



我在磁盘上有一个序列化表,我想根据条件对其进行更新。 一种方法是在内存中加载表,对其进行更新,然后在磁盘上再次序列化它。 例如:

q)`:file set ([] id:10 20; l1:("Blue hor";"Antop"); l2:("Malad"; "KC"); pcd:("NCD";"FRB") );
q)t:get `:file;
q)update l1:enlist "Chin", l2:enlist "Gor" from `t where id=10;
q)`:file set t;

我尝试直接在磁盘上更新表,但收到类型错误:

q)update l1:enlist "Chin", l2:enlist "Gor" from `:file where id=10
'type
[0]  update l1:enlist "Chin", l2:enlist "Gor" from `:file where id=10

有没有办法直接在磁盘上更新序列化表?(在一种情况下,我们没有足够的主内存来加载序列化表(

如果将表另存为一个平面文件,则必须加载、更新然后写下整个表,这需要足够的内存来保存整个表。 为了避免这种情况,您可以通过在文件路径中添加尾随/来张开您的表格,即

`:file/ set ([] id:10 20; l1:("Blue hor";"Antop"); l2:("Malad"; "KC"); pcd:("NCD";"FRB") );

如果存在符号列,则需要使用 枚举它们。问。

这将垂直拆分表,并将列另存为单个文件,位于名为 file 的目录下。将列另存为单个文件允许您仅加载所需的列而不是整个表,从而减少内存需求。您只需在选择查询中指定所需的列。

https://code.kx.com/q4m3/14_Introduction_to_Kdb%2B/#142-splayed-tables

您可以通过分区进一步水平拆分数据,如果单个列太大,则会再次生成较小的子集。

https://code.kx.com/q4m3/14_Introduction_to_Kdb%2B/#143-partitioned-tables

当您运行时

get`:splayedTable

此内存映射表,假定您的列是可映射的,而不是将其复制到内存中,如 所示。Q.w[]

你可以做

tab:update l1:enlist "Chin", l2:enlist "Gor" from (select id, l1,l2 from get`:file) where id=10
`:file/l1 set tab`l1
`:file/l2 set tab`l2

如果仅将查询所需的列加载到内存中仍然太大,则可以一次加载一个列。首先加载 id 并找到所需的索引(其中 id=10(,从内存中删除 id,在 l1 中加载并使用索引进行修改,

@[get`:file/l1;indicies;:;enlist"Chin"]

写下来,然后将其从内存中删除。然后对 l2 执行相同的操作。这样,内存中最多只有一列。理想情况下,您的表将适当分区,以便您可以将数据保存在内存中。

您也可以直接更新磁盘上的向量,从而避免必须重新写入整个文件,例如,

ind:exec i from get`:file where id=10
@[`:file/l1;ind;:;enlist"Chin"]

虽然对文件有一些限制,但在下面的链接中提到 https://code.kx.com/q/ref/amend/#functional-amend

最新更新