我的用例如下:我必须存储和查询来自多个第三方来源的数据。我拥有的唯一预定义架构知识是它由实体-属性-值元组和一个额外的源组件组成:(E, A, V, S)
. 我事先不知道会出现哪些属性(因此使用实际属性本身作为列是有问题的)。该组合(E,A,V)
必须是唯一的,因此我认为将其用作复合键是对其建模的最佳方法,因此我们得到:
CREATE TABLE t1 (
E text,
A text,
V text,
S text,
PRIMARY KEY(E, A, V)
);
这将使我能够提出以下问题:
- 给定 E,显示所有属性 A 和值 V 以及它们出现的来源 S
- 给定 E 和 A,给出所有 V。
计划是使用不同顺序的复合键创建此表的镜像,以便我还可以回答以下形式的查询:
- 给定 A,显示所有实体 E 和值 V。
- 给定 S,显示所有 E、A、V 元组。
依此类推(实际上,镜像表扮演索引的角色,为了获得完整的索引,我需要 6 个有效相同数据的副本 - 尚不确定该方法的可伸缩性,但这是一个单独的问题,我猜测)。
到目前为止一切都很好,但是,我正在努力解决的部分是:V
实际上它本身就是一个对象,具有多个属性。如果这是一个关系模型,我将V
是一个外键字段,指向一个将其映射id
到例如type
字段和value
字段的关系。但是摆脱外键(以及伴随它们的连接)或多或少是我猜 BigTable 方法的重点,所以我正在寻找一种方法将其合并到我的 table 中t1
。
当然,我可以这样做:
CREATE TABLE t1 (
E text,
A text,
V_id text,
S text,
V_type text,
V_value text,
PRIMARY KEY(E, A, V_id)
);
但我看到的问题是,这无法捕获V
id、类型和值之间的(反)函数关系:使用上表,我可以得到,例如:
E | A | V_id | V_type | V_value
---+----+------+--------+--------
a1 | b1 | 1 | X | foo
a1 | b1 | 2 | X | foo
a1 | b2 | 1 | Y | bar
虽然我希望能够确保给定的 a V_id
、 type 和 value 是唯一的,反之亦然。我想我所追求的是旧 Cassandra 版本中的嵌套超级列,但我正在尝试使用 CQL3 实现我所需要的。
我简要研究了集合类型,但这似乎不太适合我的用例。
任何人都可以建议一种更好的方法来对此进行建模,请记住,理想情况下,我希望能够检索(E, A, V)
并尽可能少地查询?还是我只是想多了,我目前拥有的方法实际上很好(我当然可以尝试确保应用程序级别的唯一性)?