2013-08-02 3 views
6

Ich bin auf der Suche nach einer effizienten Möglichkeit, Gruppen von Objekten, die während Ereignissen zusammen aufgetreten sind, so zu speichern, dass ich aggregierte Statistiken auf ihnen Tag für Tag generieren kann.Wie werden Gruppen von Objekten gespeichert, die während Ereignissen zusammen aufgetreten sind?

Um ein Beispiel zu geben, stellen wir uns ein System vor, das Besprechungen in einem Büro verfolgt. Für jedes Meeting notieren wir, wie viele Minuten es dauerte und in welchem ​​Raum es stattfand.

Ich möchte Statistiken sowohl von Person als auch von Zimmer aufgeteilt bekommen. Ich muss die einzelnen Meetings nicht im Auge behalten (also keine meeting_id oder etwas ähnliches), alles was ich wissen möchte, sind täglich zusammengefasste Informationen. In meiner realen Anwendung gibt es Hunderttausende von Ereignissen pro Tag, so dass es nicht möglich ist, jeden einzeln zu speichern.

Ich möchte in der Lage sein, Fragen zu beantworten wie: (zusammen nicht notwendigerweise)

Im Jahr 2012, wie viele Minuten haben Bob, Sam und Julie verbringen in jedem Konferenzraum?

Wahrscheinlich fein dies mit 3-Abfragen zu tun:

>>> query(dates=2012, people=[Bob]) 
{Board-Room: 35, Auditorium: 279} 
>>> query(dates=2012, people=[Sam]) 
{Board-Room: 790, Auditorium: 277, Broom-Closet: 71} 
>>> query(dates=2012, people=[Julie]) 
{Board-Room: 190, Broom-Closet: 55} 

Im Jahr 2012, wie viele Minuten haben Sam und Julie zusammen verbringen in jedem Konferenzraum Konferenz? Was ist mit Bob, Sam und Julie?

>>> query(dates=2012, people=[Sam, Julie]) 
{Board-Room: 128, Broom-Closet: 55} 
>>> query(dates=2012, people=[Bob, Sam, Julie]) 
{Board-Room: 22} 

Im Jahr 2012, wie viele Minuten pro Person im Vorstand Zimmer verbracht hat?

>>> query(dates=2012, rooms=[Board-Room]) 
{Bob: 35, Sam: 790, Julie: 190} 

Im Jahr 2012, wie viele Minuten war der Board-Raum im Einsatz?

Das ist eigentlich ziemlich schwierig, da die naive Strategie, die Anzahl der Minuten zu addieren, die jede Person ausgegeben hat, zu einem ernsthaften Überzählen führt. Aber wir können wahrscheinlich dieses Problem lösen, indem die Anzahl separat als Meta-Person Jeder Speicherung:

>>> query(dates=2012, rooms=[Board-Room], people=[Anyone]) 
865 

Was einige gute Datenstrukturen oder Datenbanken, die ich verwenden kann, um diese Art von Abfragen zu ermöglichen? Da der Rest meiner Anwendung verwendet MySQL, bin ich versucht, eine String-Spalte zu definieren, die die (sortiert) ids jeder Person in der Sitzung, aber die Größe dieser Tabelle wird wachsen ziemlich schnell hält:

2012-01-01 | "Bob"   | "Board-Room" | 2 
2012-01-01 | "Julie"   | "Board-Room" | 4 
2012-01-01 | "Sam"   | "Board-Room" | 6 

2012-01-01 | "Bob,Julie"  | "Board-Room" | 2 
2012-01-01 | "Bob,Sam"  | "Board-Room" | 2 
2012-01-01 | "Julie,Sam"  | "Board-Room" | 3 

2012-01-01 | "Bob,Julie,Sam" | "Board-Room" | 2 

2012-01-01 | "Anyone"  | "Board-Room" | 7 

Was kann ich sonst noch tun?

+1

Also, um zu klären, haben Sie eine Bajillion "Meetings" passiert, so dass Sie sie am Tag aggregieren. Das bedeutet, Sie haben Minuten für den Schnittpunkt der Kreuzungsstelle am Ort (nennen wir das R U P U D). Sie wollen R U (P1 Kreuzung P2 Kreuzung P3) U D in einer Weise, in der Sie nicht jede Sitzung speichern müssen ... – Temuz

+0

Ja genau! Wenn wir meeting_ids speichern würden, könnten wir einfach UNIQUE meeting_ids holen und dann nach Informationen für jeden einzelnen suchen, aber das wäre eine Menge Datensätze, die MySQL zusammenfassen könnte. –

+0

Sind diese Sätze der Abfrage behoben oder kann es sich ändern? Ich meine, kann es so sein wie all die Zeiten zu finden, als Julia und Bob nicht in diesem Borad-Raum waren. Ich denke, Meeting ID ist hier nicht so wichtig, da wir ein einzigartiges Meeting mit der Kombination von Zeit und BoardRoom erhalten können. – AKS

Antwort

0

Ihre Frage ist ein wenig unklar, weil Sie sagen, dass Sie nicht jedes einzelne Meeting speichern möchten, aber wie erhalten Sie dann die aktuellen Meeting-Statistiken (Daten)? Darüber hinaus kann jede Tabelle mit den richtigen Indizes sehr schnell sein, selbst bei vielen Datensätzen.

Sie sollten in der Lage sein, eine Tabelle wie log_meeting zu verwenden.Ich stelle mir es so etwas wie enthalten könnte:

employee_id, room_id, date (as timestamp), time_in_meeting 

Wo Fremdschlüssel Mitarbeiter-ID Mitarbeitertabelle und Raum id Schlüssel zum Zimmer Tisch

Wenn Sie Index Mitarbeiter-ID, Raum-ID und das Datum Sie sollten eine ziemlich schnelle Suche als mysql Multiple-Column-Indizes gehen von links nach rechts, so dass Sie Index für (Mitarbeiter-ID, Mitarbeiter-ID + Zimmer-ID und Mitarbeiter-ID + Zimmer-ID + Zeitstempel) erhalten, wenn Suchen. Dies wird mehr im Multi-Index Teil erklärt:

http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html

0

Durch die Weigerung, Sitzungen zu speichern (und verwandte Objekte) individuell, Sie die ursprüngliche Informationsquelle zu verlieren.

Sie können diesen Datenverlust nicht kompensieren, es sei denn, Sie merken sich regelmäßig die umfangreiche Liste aller potenziellen täglichen (oder monatlichen oder wöchentlichen oder ...) Aggregate, die Sie später noch einmal fragen müssen !

Glauben Sie mir, es wird ein Alptraum sein ...

0

Wenn die Zahl der Menschen sind konstant und nicht sehr groß Sie können dann eine Spalte für jede Person für aktuelle zuweisen oder nicht, und speichern Sie das Zimmer, das Datum und Zeit in 3 weiteren Spalten kann dies die String-Splitting-Probleme entfernen.

Auch durch die Art Ihrer Frage fühle ich vor allem Sie müssen Ids zu allen Räumen, Menschen, etc. zuweisen. Keine Notwendigkeit für lange sich wiederholende Zeichenfolge in der DB. Versuchen Sie auch, die Zeichenfolgenoperation zu reduzieren und arbeiten Sie mit einzelnen Daten in jeder Spalte, um eine bessere Schnittleistung zu erzielen. Sie können auch eine Permutation aller Personen in einer Tabelle speichern und ihnen eine ID zuweisen. Verwenden Sie dann eine dieser IDs in der aktuellen Datums- und Zeittabelle. Aber alle Techniken erfordern, dass etwas konstant ist entweder Menschen oder Räume.

0

Ich verstehe nicht, ob Sie alle "Fragen" in der Entwurfszeit kennen oder es ist möglich, neue während der Entwicklungs-/Produktionszeit hinzuzufügen - dieser Ansatz würde erfordern, alle Daten die ganze Zeit zu behalten.

Nun, wenn Sie alle Ihre Fragen kennen würden, scheint es wie klassische "Banking-System", die Daten auf täglicher Basis neu berechnet.

Wie ich darüber denke.

  1. Scheint, wie Sie die Zahl der Zimmer beschränkt haben, Menschen, Tage usw.
  2. Sammeln Logging-Daten auf täglicher Basis, eine Tabelle pro Tag. Nur ein Ereignis, eine Datenbankzeile, alle Informationen (Feld), was Sie brauchen.
  3. Starten Sie die Analyse von Daten mit einigen Crone-Skript bei "Mitternacht".
  4. Aktualisieren Sie die Statistiken für Personen, Räume usw. Erhöhen Sie einfach die Anzahl der Stunden, die Bob im xyz-Raum usw. verbracht hat. Alles, was Sie benötigen.
  5. Wie analysierten Daten begrenzt und relativ klein sind, wie Sie analysiert (komprimieren) sie können Ihr System verschiedene Abfragen enthalten auch als Indizes relativ klein usw.

wäre Sie in der Lage sein könnte, skalierbare Karte verwenden/reduzieren Algorithmus.

0

Sie können nicht vermeiden, die atomaren Fakten wie folgt zu speichern: (der Besprechungsraum, die Personen, die Dauer, der Tag), was wahrscheinlich nur eine schwache Konsolidierung ist, wenn die gleichen Leute sich mehrmals im selben Raum treffen am selben Tag.Vielleicht passiert das viel in Ihrem Büro :).

Gruppen vergleichbar zu machen ist ein interessantes Problem, aber solange Sie die Element-Strings immer gleich zusammensetzen, können Sie dies wahrscheinlich mit String-Vergleichen tun. Dies ist jedoch nicht "normal". Zur Normalisierung benötigen Sie eine Relationstabelle (viele zu viele) und erstellen eine temporäre Tabelle aus Ihrem Abfrage-Set, um sie schnell zu verknüpfen. Sie können auch eine IN-Klausel und ein Zähl-Aggregat verwenden, um sicherzustellen, dass alle Personen vorhanden sind was ich meine, wenn du es versuchst).

Ich denke, Sie können die Minuten, die der Board-Room verwendet wurde, ableiten, da Meetings sich nicht überschneiden sollten, also wird eine Summe funktionieren.

Verwenden Sie für die Speichereffizienz Ganzzahlschlüssel für alles mit Nachschlagetabellen. Dereferenzieren Sie die Ganzzahlen während der Abfrageanalyse, oder verwenden Sie nur gute alte Verknüpfungen, wenn Sie sich traditionell fühlen.

So würde ich es trotzdem machen :).

Verwandte Themen