Eine mysql-Abfrage optimieren, um "unsichtbare" Einträge pro Benutzer zu holen

9

Dieser Titel ist ziemlich faszinierend, aber ich konnte mir nichts klarer vorstellen.

Kurz gesagt, wir erstellen eine mobile App, die mit einem node.js-Server verbunden ist, der mit einer mySql-Datenbank kommuniziert. Ziemlich allgemeines Setup. Jetzt haben wir mehrere Benutzer verbunden, die "Momente" auf unsere Server hochladen können. Diese Momente können von allen anderen Benutzern nur einmal gesehen werden.

Sobald ein Benutzer x den Moment eines anderen Benutzers sieht, kann x diesen Moment nie sehen. Vielleicht ein bisschen wie bei Snapchat, außer dass der Moment für einen einzelnen Benutzer auf mehrere Benutzer beschränkt ist, statt auf Single. Die Momente sind auch nach Entfernung sortiert, abhängig vom aktuellen Standort des Benutzers.

Nun suche ich nach einem intelligenten Weg, um nur die "unsichtbaren" Momente aus der Datenbank zu holen. Im Moment verwenden wir eine relationale Tabelle zwischen Benutzern und Momenten.

Nehmen wir an, ein Benutzer (ID = 20) sieht einen Moment (ID = 30320), dann fügen wir in diese Tabelle 20 und 30320 ein. Ich weiß. Dies ist kaum skalierbar und wahrscheinlich eine schreckliche Idee.

Ich dachte daran, vielleicht das letzte gesehene Datum zu überprüfen und nur Augenblicke nach diesem Datum abzurufen, aber wieder sind die Momente nach Entfernung sortiert, bevor man nach Datum sortiert, so dass man einen Moment von 3 Minuten sehen kann ein Moment, der 30 Sekunden alt ist.

Gibt es eine cleverere Methode, dies zu tun, oder bin ich dazu verdammt, eine Beziehungstabelle zwischen Moments und Benutzern zu verwenden und sich ihr bei der Abfrage anzuschließen?

Vielen Dank.

BEARBEITEN -

Diese Logik verwendet insgesamt 3 Tabellen.

  • Benutzer
  • Momente
  • MomentSeen

MomentSeen enthält nur, was der Benutzer wann und wann gesehen hat. Da die Momente nicht nach Datum sortiert sind, kann ich nicht alle Momente abrufen, die nach dem letzten gesehenen Moment hochgeladen wurden.

BEARBEITEN -

Ich habe gerade die mobile App Tinder muss ähnliche Logik für welche Benutzer "gemocht", welche anderen Benutzer. Da Sie nicht in der Zeit zurückgehen und einen Benutzer zweimal sehen können, verwenden sie wahrscheinlich eine sehr ähnliche Abfrage als das, wonach ich suche.

Wenn man bedenkt, dass sie viele Benutzer haben und nach Entfernung und einigen anderen unbekannten Kriterien geordnet sind, muss es einen schlaueren Weg geben, Dinge zu tun als eine relationale Tabelle "UserSawUser".

BEARBEITEN

Ich kann nicht die gesamte Datenbankstruktur bereitstellen, also überlasse ich nur die wichtigen Tabellen und einige ihrer Felder.

%Vor%     
Érik Desjardins 28.07.2015, 20:07
quelle

3 Antworten

1

Sie können den Bloom-Filter implementieren. Es wird häufig verwendet, um Festplattensuchvorgänge zu reduzieren und eine bessere Leistung zu erzielen.

Medium verwendet es, um zu prüfen, ob ein Benutzer bereits einen Beitrag gelesen hat.

Weitere Details hier -
Ссылка Ссылка

    
Brainhash 11.08.2015 19:14
quelle
0

Verwenden Sie nicht eine Tabelle pro Benutzer. Haben eine einzige Tabelle für die Momente.

Sie scheinen zwei widersprüchliche Ordnungen für "Momente" zu haben: "Distanz" und "ungesehen"; Was ist das?

Wenn es "unsichtbar" ist, sind die "Momente" chronologisch nummeriert? Dies bedeutet, dass jeder Benutzer ein last_moment_seen - all Moments hat, bevor er gesehen wurde; Alle danach wurden nicht gesehen. Also ...

%Vor%

würde alle Momente erhalten, die für einen bestimmten Benutzer noch nicht sichtbar sind.

Munch für eine Weile; die kommen für weitere Vorschläge zurück.

Bearbeiten

Dies sollte Ihnen die Momente geben, die Sie noch nicht gesehen haben. Sie können sie dann so bestellen, wie Sie es für richtig halten.

%Vor%     
Rick James 29.07.2015 20:58
quelle
0

Warum zögern Sie nicht mit Join? Haben Sie versucht, Ihre Datenbank mit Dummy-Daten zu füllen? Millionen von ihnen in der Lage, Leistungseinbußen auf Ihrem System zu messen?

Die Verwendung von Joins ist keine so schlechte Idee und ist oft schneller als eine einzelne Tabelle, wenn dies richtig gemacht wird.

Sie sollten wahrscheinlich das Datenbankdesign recherchieren, um eine Referenz zu finden.

Zum Beispiel erfolgt die Bestellung einer Tabelle mit einem Index. Sie können jedoch mehr als einen Index für eine Tabelle und eine Kombination von Spalten für jeden Index verwenden. Dies kann durch Analysieren der häufig verwendeten Abfragen für die Tabelle erfolgen. Ein praktisches Rezept besteht darin, einen Index zu erstellen, der eine Spaltengruppe enthält, die in Join-Schlüsseln verwendet wird, einen weiteren Index für jede mögliche "where" -Parameterkombination als Spaltenindex und eine Reihe von Indexspalten für jeden Abfrageabfragebefehl gegen diese Tabelle (die aufsteigende / absteigende Reihenfolge war wichtig).

Seien Sie also nicht schüchtern, um eine weitere Spalte und einen Index hinzuzufügen, die Ihren Anforderungen entsprechen.

Wenn Sie von Skalierbarkeit sprechen, sollten Sie die Datenbank-Engine optimieren. z.B. Machen Sie einen höheren möglichen Schlüssel mit großen Integer.      Die Verwendung eines Datenbank-Cluster-Setups würde auch eine Tiefenanalyse erfordern, da Autoinkrement-Schlüssel in einem Multi-Master-Setup Probleme verursachen.

Wenn Sie versuchen, mehr Leistung von Ihrem System zu erhalten, sollten Sie die gesamte Datenbank von Anfang an als tabellenpartitionsfreundlich betrachten. Dazu gehört eine ernsthafte Analyse Ihrer Geschäftsregel. Um eine tabellenpartitionsfreundliche Umgebung zu erstellen, müssen Sie eine Spalte als Schlüssel einrichten und die Daten physisch aufteilen (denken Sie daran, file_per_table = 1 auf mysql config zu setzen, da sonst der Vorteil der Tabellenpartitionierung verloren geht). Wenn das nicht richtig gemacht wird, wird die Partitionierung für Sie keinen Vorteil bringen.

Ссылка

    
Henry Eko 09.08.2015 01:04
quelle

Tags und Links