2016-06-21 16 views
1

Sagen wir, wir haben Nutzer, die Videos kommentieren können und wir möchten alle Kommentare per Video mit dem Nutzernamen anzeigen. Der Benutzer kann auch auf seine Profilseite gehen und seinen Namen ändern.Aktualisieren Sie die denormalisierten Daten in Cassandra

Basierend auf Cassandra Datenmodellierung Praktiken, die Cassandra denormalization datamodel in dieser Antwort bedeckt waren, ich habe solche Tabellen erstellen:

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) 
); 

genial aussieht, können wir Daten bekommen, die Kommentare von Video zu zeigen, benötigten nur durch eine Abfrage .

Betrachten wir nun einen solchen Anwendungsfall.

Benutzer erstellt viele Kommentare (wie 10 000) und entschied sich dann, seinen Namen zu ändern. Sollten wir alle Kommentare aktualisieren, um seinen Namen zu ändern? Gibt es eine Möglichkeit, es effizient zu machen?

+0

Haben Sie mehr Einblick in das Thema gewonnen? Ich denormalisierte meine Kommentare wie hier und ich frage mich, was passiert, wenn der Benutzer sie ändert? –

Antwort

0

Herzlichen Glückwunsch, Sie betreten nur die relationale Datenbankzone!

Ernsthafter ist diese Anforderung ein Schmerz mit Ihrem Modell. Entweder müssen Sie user_id verwenden, um und first name in users Tabelle für jeden Kommentar bei Lesevorgänge abzufragen, oder Sie müssen über alle Partitionen und alle Kommentare suchen, um die first_name und last_name überall zu ersetzen. Es gibt keine Möglichkeit, es effizient zu machen.

Aber versuchen wir einen naiven Ansatz. Sie könnten eine Benutzer-Tabelle, ein Video-Tabelle erstellen und eine andere Tabelle, die alle Kommentare eines Benutzers speichern wie diese:

CREATE TABLE users_videos_comment(
    user_id uuid, 
    video_id uuid, 
    time timestamp, 
    comment text, 
    PRIMARY KEY ((user_id,video_id), time) 
); 

Das ist effizient für die neue Anforderung für einen Benutzer und ein Video, das Sie alle Kommentare bekommen , so müssen Sie nur die Benutzer abfragen, um nach dem Namen zu suchen, aber Sie verlieren die "eine Abfrage für alle Kommentare in einem Video". Außerdem müssen Sie in users eine Liste des Videos speichern, in dem ein Benutzer kommentierte, und auf videos eine Liste der Benutzer, die Kommentare gemacht haben. Dies ist schwierig zu warten und erfordert etwas mehr Code.

Es gibt vielleicht bessere Möglichkeiten, es zu tun, aber nicht vergessen, mit NoSQL Was Sie schreibt verlieren, gewinnen Sie auf liest

Wenn Sie nicht viel schreibt tun nichts dagegen, den Benutzernamen zu ändern, dann behalte es so wie es ist. Von diesem post, scheint Cassandra sowieso besser für Schreibvorgänge, also sollten Sie daran denken, die Lesevorgänge zu optimieren.

In diesem Sinne können wir ein Feld in users hinzufügen, die alle Kommentare von einem Benutzer aufgelistet. Auf diese Weise müssen Sie nicht über comments_by_video scannen, um nach allen Kommentaren eines Benutzers zu suchen. Dies führt zu einer gewissen Komplexität, da Sie für alle Kommentare eines Benutzers zwei Schreibvorgänge ausführen müssen (und sicherstellen, dass es konsistent ist). Aber Sie haben beide Anforderungen erfüllt.

Hoffe es hilft

+0

es passt nicht zu dir? – Whitefret

+0

Ja, ich habe mir diese Möglichkeiten schon gedacht. Im Fall von 'users_videos_comment' haben wir' n + 1' Problem, also wenn 1000 von 1000 verschiedenen Benutzern kommentiert wurde, dann werden 1000 + 1000 + 1 (oder nur 1000 + 1 wenn wir den Namen nicht speichern) das 'comments_by_video'). 'videos_where_user_made_comment' oder speichern Sie Kommentare/Videos in' user' Tabelle scheint wie effizienteste Weg für den Moment. – NikolayS

+0

Entschuldigung, ich habe meine vorherigen Kommentare gelöscht, da ich sie nicht bearbeiten kann. – NikolayS