Frage

Ich arbeite auf einer Website mit einer einfachen normalisierte Datenbank.

Es gibt eine Tabelle namens Pages und eine Tabelle namens Ansichten. Jedes Mal, wenn eine Seite betrachtet wird, eine einmalige Aufzeichnung dieser Ansicht ist in den Ansichten Tabelle aufgezeichnet.

Wenn Sie eine Seite auf der Website angezeigt wird, habe ich eine einfache MySQL COUNT () verwenden, um die Anzahl von Ansichten für die Anzeige auf insgesamt bis.

Datenbank-Design scheint in Ordnung, außer für dieses Problem:. Ich ratlos bin dafür, wie die Top 10 der am häufigsten betrachteten Seiten unter Tausenden abrufen

Soll ich denormalize die Seiten-Tabelle durch eine Pages.views Spalte Addieren der Gesamtzahl der Aufrufe für jede Seite zu halten? Oder gibt es eine effiziente Möglichkeit für die Top-10 der am häufigsten betrachteten Seiten abfragen?

War es hilfreich?

Lösung

   SELECT p.pageid, count(*) as viewcount FROM 
   pages p
   inner join views v on p.pageid = v.pageid
   group by p.pageid
   order by count(*) desc   
   LIMIT 10 OFFSET 0;

Das kann ich nicht testen, aber etwas in diese Richtung. Ich würde den Wert nicht speichern, wenn ich zu Leistungseinschränkungen zurückzuführen (ich habe gerade erfahren, den Begriff „vorzeitige Optimierung“, und es scheint gelten, wenn Sie tun).

Andere Tipps

Es hängt von der Höhe der Informationen, die Sie zu halten versuchen. Wenn Sie aufnehmen möchten, die sich, wenn? Dann wird die separate Tabelle ist in Ordnung. Andernfalls wird eine Spalte für Ansichten ist der Weg zu gehen. Wenn Sie auch eine separate Spalte halten, werden Sie öfter gesperrt wird die Tabelle, da jede Seite Ansicht finden, die versuchen, die Spalte für die entsprechende Zeile zu aktualisieren.

Select pageid, Count(*) as countCol from Views
group by pageid order by countCol DESC
LIMIT 10 OFFSET 0;

Ich würde wahrscheinlich auch die Ansichten Spalte in den Seiten-Tabelle.

Es scheint wie ein durchaus vernünftiger Bruch der Normalisierung zu mir. Vor allem, da kann ich nicht vorstellen, dass Sie das Löschen Ansichten so würden Sie nicht die Zählung erwarten aus dem Gleichgewicht geraten zu bekommen. Referentielle Integrität scheint nicht überkritische in diesem Fall.

Datenbank Normalisierung dreht sich alles um die effizienteste / dest redundant Daten zu speichern. Das ist gut für die Transaktionsverarbeitung, aber oft in Konflikt direkt mit der Notwendigkeit, die Daten effizient wieder raus. Das Problem in der Regel, indem abgeleitete Tabellen angesprochen wird (Indizes, materialisierten Sichten, Rollup Tabellen ...) mit zugänglichen, vorverarbeiteten Daten. Die (etwas veraltet) Schlagwort hier ist Data Warehousing.

Ich glaube, Sie Ihre Seiten Tabelle normalisiert behalten möchten, haben aber eine zusätzliche Tabelle mit den Summen. Je nachdem, wie kürzlich müssen diese Zählungen sein, können Sie die Tabelle aktualisieren, wenn Sie die ursprüngliche Tabelle aktualisieren, oder Sie können einen Hintergrund-Job haben, um periodisch die Summen neu zu berechnen.

Sie wollen auch dies nur tun, wenn Sie wirklich ein Performance-Problem führen, die Sie nicht, wenn Sie eine sehr große Anzahl von Datensätzen haben, oder eine sehr große Anzahl von gleichzeitigen Zugriffen. Halten Sie Ihren Code flexibel der Lage sein, um zwischen den Tisch zu haben und nicht mit ihm.

Denormalisierung würde auf jeden Fall in diesem Fall arbeiten. Ihr Verlust ist der zusätzliche Stauraum durch die zusätzliche Spalte verbraucht.

Alternativ können Sie einen geplanten Auftrag einrichten, um diese Informationen auf einer nächtlichen Basis zu füllen, wenn Ihr Verkehr niedrig ist, x Zeit.

In diesem Fall würden Sie verlieren die Fähigkeit, sofort Ihre Seite zählt wissen, wenn Sie diese Abfrage manuell ausführen.

Denormalisierung kann auf jeden Fall eingesetzt werden, die Leistung zu erhöhen.

- Kris

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top