Cassandra 3中的多对多

时间:2017-06-14 17:13:25

标签: cassandra many-to-many cql cassandra-3.0

在Cassandra中建立多对多关系的正确方法是什么(目前使用3.10)?

从我能够找到的答案中,建议将非规范化分解为两个关系表(如此处,例如:Modeling many-to-many relations in Cassandra 2 with CQL3)。但是在删除方面存在问题,而且这些答案非常稀少,他们没有提及任何细节。

假设我们有以下表格:

CREATE TABLE foo (
  key UUID PRIMARY KEY,
  content TEXT
)
CREATE TABLE bar (
  key UUID PRIMARY KEY,
  content TEXT
)
CREATE TABLE foo_bar (
  foo UUID,
  bar UUID,
  PRIMARY KEY (foo, bar)
)
CREATE TABLE bar_foo (
  bar UUID,
  foo UUID,
  PRIMARY KEY (bar, foo)
)

这似乎是建议的答案。但是,当我们尝试删除bar记录时会发生什么?更新bar_foo表非常简单:

DELETE FROM bar_foo WHERE bar = <bar_key>

但是,尝试更新foo_bar表失败:

DELETE FROM foo_bar WHERE bar = <bar_key>

出现以下错误:

InvalidRequest: Error from server: code=2200 [Invalid query] message="Some partition key parts are missing: foo"

这是因为foo_bar表的主键是(foo, bar),我们只在DELETE语句的WHERE子句中指定主键的第二部分。显然,Cassandra需要主键的前缀,没有bar的{​​{1}}不是前缀。

现在,将主键更改为foo不会有帮助。毕竟,如果(bar, foo)记录被删除,你会怎么做?并且,在任何情况下,foo表的整个目的是能够找到与给定foo_bar记录对应的所有bar记录,以及SELECT语句也< / em>需要WHERE子句中的主键前缀(必须是foo)。

不能执行SELECT,然后执行DELETE,因为foo的SELECT不起作用,它不是主键的前缀。

那么,当图片中有删除时,如何处理多对多关系?这甚至可以正确完成吗?

2 个答案:

答案 0 :(得分:0)

CREATE TABLE foo (
  key UUID PRIMARY KEY,
  content TEXT
)
CREATE TABLE bar (
  key UUID PRIMARY KEY,
  content TEXT
)
CREATE TABLE foo_bar (
  foo UUID,
  bar UUID,
  PRIMARY KEY (foo, bar)
)
CREATE MATERIALIZED VIEW bar_foo AS
  SELECT bar, foo FROM foo_bar
    WHERE foo IS NOT NULL AND bar IS NOT NULL
  PRIMARY KEY (bar, foo)

答案 1 :(得分:0)

使用套装。 https://docs.datastax.com/en/cql/3.3/cql/cql_using/useSet.html

CREATE TABLE foo (
  key UUID PRIMARY KEY,
  content TEXT
)
CREATE TABLE bar (
  key UUID PRIMARY KEY,
  content TEXT
)
CREATE TABLE foo_jn_bar (
  foo UUID PRIMARY KEY,
  bar set<UUID>
)
CREATE TABLE bar_jn_jn (
  bar UUID PRIMARY KEY,
  foo set<UUID>
)

如果你遵循关系习惯,你将在磁盘数据方面存在巨大的不一致。