代码之家  ›  专栏  ›  技术社区  ›  SkyWalker

kdb:用复合外键连接两个表的惯用方法是什么?

kdb
  •  2
  • SkyWalker  · 技术社区  · 7 年前

    我有两张桌子 t1 t2 定义为:

    t1:([a:`datetime$(); b:`$()] x:`float$(); y:`float$());
    meta t1
    > c| t f a
    > -| -----
    > a| z    
    > b| s    
    > x| f    
    > y| f 
    
    t2:([t1:`t1$(); c:`$()] z:`float$());
    meta t2
    > c | t f  a
    > --| ------
    > t1| i t1  
    > c | s     
    > z | f 
    

    哪里 从属性定义复合主键 a b 定义forein键 至表格 t1 .

    ej[`t1;update t1:`t1$(a,'b) from t1;t2]
    > a b x y t1 c z
    > --------------
    

    基本上在表之间进行平等连接 t2 t1 公开复合外键,即列类型 . 有没有更地道、更简单的方法?例如做 t2 ij t1 导致 error: ``a

    1 回复  |  直到 7 年前
        1
  •  2
  •   Jonathon McMurray    7 年前

    稍微高效一点&更简洁的方法是在kdb表中使用隐藏的i列(即行索引),而不是生成t1和;根据t1枚举,例如。

    q)ej[`t1;update t1:`t1!i from t1;t2]
    a b x y t1 c z
    --------------
    

    这稍微更有效:

    q)\ts:1000 ej[`t1;update t1:`t1!i from t1;t2]
    11 1904
    q)\ts:1000 ej[`t1;update t1:`t1$(a,'b) from t1;t2]
    12 2256
    

    (当然,效率增益将随着填充表的增加而增加)


    编辑:

    另一种选择是在select语句中使用外键,例如:

    select t1.a,t1.b,t1.x,t1.y,c,z from t2

    这比使用实际连接要高效得多:

    q)\ts:1000 select t1.a,t1.b,t1.x,t1.y,c,z from t2
    2 1712
    q)\ts:1000 ej[`t1;update t1:`t1!i from t1;t2]
    12 2496
    

    缺点是必须命名select语句中的所有字段。

    涉及连接的另一个选项是使用t2中的“t1”列索引到t1,然后连接每个记录。为此,您必须使用0!要取消索引表格,请执行以下操作:

    q)((0!t1)@(0!t2)`t1),'t2
    t1 c  | a                       b   x         y        z
    ------| -------------------------------------------------------
    0  gck| 2004.02.13T15:53:44.342 ndd 4.49731   7.833686 9.030751
    1  job| 2001.07.22T05:29:31.118 hpb 0.1392076 4.099561 7.750292
    

    (我添加了一些虚拟记录进行演示)

    这比select语句的效率略低,但比ej更好:

    q)\ts:1000 ((0!t1)@(0!t2)`t1),'t2
    4 1920