Управляйте многими отношениями в Кассандре - PullRequest
0 голосов
/ 05 ноября 2018

У меня есть две таблицы:

create table users (
    id UUID,
    email ascii,
    created_at timeuuid,
    primary key(id, email)
);
create table groups (
    id UUID,
    name ascii,
    created_at timeuuid,
    primary key(id, name)
);

Пользователь может быть в нескольких группах, в группе может быть несколько пользователей.

Итак, у меня есть два способа поддерживать отношения «многие ко многим» (взято из здесь ), один из них:

CREATE TABLE user_group (
  user UUID,
  group UUID,
  PRIMARY KEY (user, group)
)

Еще один (с использованием наборов):

CREATE TABLE user_jn_group (
  user UUID PRIMARY KEY,
  groups set<UUID>
)
CREATE TABLE group_jn_user (
  group UUID PRIMARY KEY,
  users set<UUID>
)

Я использую Cassandra 3.9.0. Я знаю, что оба подхода имеют свои преимущества, недостатки. Я хочу наименьшего двуличия, но у меня есть равный вес для скорости чтения / записи. Кроме того, есть ли еще какие-то скрытые затраты за оба этих подхода?

1 Ответ

0 голосов
/ 05 ноября 2018

Использование коллекций для этого, вероятно, нецелесообразно из-за ограничения размера коллекций (хотя это не должно беспокоить систему с несколькими пользователями), высока вероятность того, что набор пользователей в группе будет слишком большой.

Стоит также отметить, что ваше решение на основе таблицы user_group не будет работать, поскольку оно не будет поддерживать запросы по группам. Вам нужно будет сохранить другую таблицу для поддержки этого запроса (и всегда поддерживать две записи):

CREATE TABLE group_user (
  user UUID,
  group UUID,
  PRIMARY KEY (group, user)
)

Это позволит выполнять запросы по группам.


Дополнительные опции:

Добавить вторичный индекс к user_group:
Другой подход заключается в расширении решения user_group: если у вас есть вторичный индекс в поле group, вы сможете выполнять поиск в обоих направлениях:

CREATE INDEX ON user_group (group);

Использовать материализованное представление
Вы также можете использовать материализованное представление вместо таблицы group_user. Данные между user_group и этим представлением будут синхронизироваться cassandra (в конце концов):

CREATE MATERIALIZED VIEW group_user
AS SELECT group, user
FROM user_group
WHERE user IS NOT NULL AND group IS NOT NULL
PRIMARY KEY (group, user);

При этом вам нужно будет добавить запись только к user_group, и представление позаботится о поиске по группе.

Как вы заметили, у каждого есть свои плюсы и минусы, которые не могут быть подробно описаны здесь. Пожалуйста, проверьте документы по ограничениям каждого варианта.

...