Обновление денормализованных данных в Cassandra


Допустим, у нас есть пользователи, которые могут комментировать видео, и мы хотим показать все комментарии по видео с именем пользователя. Также пользователь может перейти на страницу своего профиля и изменить свое имя.

Основываясь на практике моделирования данных Cassandra, которая была рассмотрена в этом ответе Cassandra denormalization datamodel , я создал такие таблицы:

CREATE TABLE users (
   user_id UUID,
   first_name TEXT,
   last_name TEXT,
   PRIMARY KEY ((user_id))
); 

CREATE TABLE comments_by_video (
   video_id UUID,
   added_at TIMESTAMP,
   user_id UUID,
   comment TEXT,
   first_name TEXT,
   last_name TEXT,
   PRIMARY KEY ((video_id), added_at, user_id)
);

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

Теперь рассмотрим такое использование дело.

Пользователь создал много комментариев (например, 10 000), а затем решил изменить свое имя. Должны ли мы обновить все комментарии, чтобы изменить его имя? Есть ли способ сделать его эффективным?

1 2

1 ответ:

Поздравляю, вы просто войти в зону базы сравнения !

Более серьезно, это требование является болью для вашей модели. Либо вы должны использовать user_id для запроса last_name и first name в таблице users для каждого комментария при чтении, либо вам нужно искать все разделы и все комментарии, чтобы заменить first_name и last_name везде. Нет никакого способа сделать его эффективным.

Однако давайте попробуем наивный подход. Вы можете создать таблицу пользователей, таблицу видео и другую таблицу. таблица, в которой хранятся все комментарии пользователя, как эта:
CREATE TABLE users_videos_comment(
    user_id uuid,
    video_id uuid,
    time timestamp,
    comment text,
    PRIMARY KEY ((user_id,video_id), time)
);

Это эффективно для вашего нового требования, для пользователя и видео вы можете получить все комментарии, поэтому вам просто нужно запросить пользователей, чтобы найти имя, но вы теряете "один запрос для всех комментариев в видео". Кроме того, вы должны хранить в users список видео, где пользователь прокомментировал, и в videos список пользователей, которые сделали комментарии. Это трудно поддерживать и потребует еще немного кода.

Возможно, есть лучшие способы сделать это, но помните, что с noSQL то, что вы теряете на записи, вы получаете на чтении

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

Имея это в виду, мы можем добавить поле в users, которое перечисляет все комментарии, сделанные пользователем. Таким образом, вам не придется сканировать comments_by_video, чтобы найти все сделанные комментарии. пользователем. Это добавляет некоторую сложность, потому что для любых комментариев, сделанных пользователем, вы должны сделать две записи (и убедиться, что это непротиворечиво). Но вы оба требования выполнили.

Надеюсь, это поможет