Как правильно смоделировать отношения «многие ко многим» в Cassandra (используя 3.10 на данный момент)?
Из ответов, которые я смог найти, предлагается денормализация в две таблицы отношений (как здесь, например: Моделирование отношений "многие ко многим" в Cassandra 2 с помощью 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)
, и мы указываем только вторую часть первичного ключа в предложении WHERE инструкции DELETE. Cassandra, видимо, требует префикс первичного ключа, а bar
без foo
префиксом не является.
Теперь изменение первичного ключа на (bar, foo)
не поможет. В конце концов, что бы вы сделали, если бы запись foo
была удалена? И, в любом случае, вся цель таблицы foo_bar
состоит в том, чтобы иметь возможность найти все записи bar
, соответствующие данной записи foo
, а оператор SELECT также требует префикса первичного ключа в Предложение WHERE (которое по необходимости должно быть foo
).
Невозможно выполнить SELECT, а затем DELETE, поскольку SELECT по bar
не будет работать, поскольку он не является префиксом первичного ключа.
Итак, что делать с отношениями «многие ко многим», когда на картинке есть удаления? Возможно ли это сделать должным образом?