在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不起作用,它不是主键的前缀。
那么,当图片中有删除时,如何处理多对多关系?这甚至可以正确完成吗?
答案 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>
)
如果你遵循关系习惯,你将在磁盘数据方面存在巨大的不一致。