2013-08-02 7 views
6

Szukam wydajnego sposobu przechowywania zestawów obiektów, które wystąpiły razem podczas wydarzeń, w taki sposób, że mogę generować na nich zbiorcze statystyki codziennie.Jak przechowywać zestawy obiektów, które wystąpiły razem podczas zdarzeń?

Aby wymyślić przykład, wyobraźmy sobie system, który śledzi spotkania w biurze. Na każde spotkanie rejestrujemy ile minut trwało i w którym pokoju miało miejsce.

Chcę otrzymywać statystyki w podziale zarówno na osobę, jak i pokój. Nie muszę śledzić pojedynczych spotkań (więc nie ma żadnych informacji), wszystko, co chcę wiedzieć, to codzienne informacje zbiorcze. W mojej prawdziwej aplikacji są setki tysięcy zdarzeń dziennie, więc przechowywanie każdego z nich indywidualnie nie jest wykonalne.

Chciałbym być w stanie odpowiedzieć na takie pytania jak:

W 2012 roku, ile minut czy Bob, Sam i Julie wydać w każdej sali konferencyjnej (niekoniecznie razem)?

Prawdopodobnie w porządku to zrobić z 3 zapytania:

>>> 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} 

w 2012 roku, ile minut udało Sam i Julie spędzają zgromadzenia, wraz z każdej sali konferencyjnej? A co z Bobem, Samem i Julie razem?

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

W 2012 roku, ile minut nie każda osoba spędzić w Zarządzie-pokojowe?

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

W 2012 roku, ile minut był Board-Room w użyciu?

Jest to dość trudne, ponieważ naiwna strategia podsumowania liczby minut, które wydała każda osoba, spowoduje poważne zliczanie. Ale prawdopodobnie możemy rozwiązać ten problem przez przechowywania liczbę osobno jako meta-osobowej Anyone:

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

Jakie są dobre struktury danych lub bazy danych, które można użyć w celu umożliwienia tego rodzaju zapytań? Ponieważ reszta mojej aplikacji wykorzystuje MySQL, jestem kuszony, aby zdefiniować kolumnę, która posiada ciąg (-i) identyfikatory każdej osoby w spotkaniu, ale rozmiar tej tablicy będzie rosnąć bardzo szybko:

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 

Co jeszcze mogę zrobić?

+1

Aby wyjaśnić, odbywają się "spotkania" w bajillionach, więc sumujesz je w ciągu dnia. Oznacza to, że masz minuty spędzone na skrzyżowaniu osób w punkcie przecięcia pokoju (nazwijmy to R U P U D). Chcesz R U (P1 przecięcie P2 przecięcia P3) U D w sposób, w którym nie musisz przechowywać każdego spotkania ... – Temuz

+0

Tak, dokładnie! Gdybyśmy zapisali wartości meeting_ids moglibyśmy po prostu pobrać UNIQUE meeting_ids, a następnie wyszukać informacje dla każdego z nich, ale byłoby to mnóstwo rekordów dla agregacji MySQL. –

+0

Czy te zestawy zapytań są poprawione, czy może się zmienić? Chodzi mi o to, że można tak znaleźć wszystkie czasy, kiedy Julia i Bob nie byli w tym spotkaniu w pokoju Borada. Sądzę, że Identyfikacja Spotkań nie ma aż tak dużego znaczenia, ponieważ możemy uzyskać unikalne spotkanie z wykorzystaniem kombinacji czasu i Pokoju. – AKS

Odpowiedz

0

Twoje pytanie jest trochę niejasne, ponieważ mówisz, że nie chcesz zapisywać poszczególnych spotkań, ale w jaki sposób otrzymujesz aktualne statystyki spotkań (daty)? Ponadto każda tabela z odpowiednimi indeksami może być bardzo szybka nawet przy wielu rekordach.

Powinieneś być w stanie użyć tabeli podobnej do log_meeting.Wyobrażam sobie to może zawierać coś takiego:

employee_id, room_id, date (as timestamp), time_in_meeting 

Gdzie klucze obce dla id pracownika do tabeli pracowników i pokojowej identyfikator klucza do tabeli pokojowej

Jeśli id ​​pracownik indeksu, id pokój i datę należy mieć dość szybkie wyszukiwanie, ponieważ indeksy mysql z wieloma kolumnami idą od lewej do prawej, dzięki czemu można uzyskać indeks (id pracownika, identyfikator pracownika + identyfikator pokoju i identyfikator pracownika + identyfikator pokoju + znacznik czasu) podczas wyszukiwania. Jest to wyjaśnione w części multi-indeksu:

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

0

Odmawiając przechowywać spotkania (i związanych z nimi obiektów) indywidualnie, jesteś utraty oryginalnego źródła informacji.

Nie będziesz w stanie zrekompensować tej utraty danych, o ile nie zapamiętasz na stałe obszernej listy wszystkich potencjalnych dziennych (lub miesięcznych lub tygodniowych lub ...) danych zagregowanych, które mogą być wymagane w późniejszym czasie. !

Wierzcie mi, to będzie koszmar ...

0

Jeżeli liczba ludzi są stałe i nie bardzo duży można następnie przypisać kolumny do każdej osoby na obecne lub nie i przechowywać pokój, data a czas w 3 kolejnych kolumnach może usunąć problemy z dzieleniem struny.

Również z natury twojego pytania czuję przede wszystkim, że musisz przypisać identyfikatory do wszystkich pomieszczeń, ludzi itp. Nie ma potrzeby ciągłego powtarzalnego łańcucha w DB. Spróbuj także zredukować dowolną operację ciągową i pracować, używając indywidualnych danych w każdej kolumnie dla lepszej wydajności przecięcia. Możesz także przechowywać permutację wszystkich osób w tabeli i przypisać im identyfikator, a następnie użyć jednego z tych identyfikatorów w rzeczywistej tabeli daty i czasu. Ale wszystkie techniki będą wymagać, aby coś było stałe albo dla ludzi, albo dla pomieszczeń.

0

Nie rozumiem, czy znasz wszystkie "pytania" w czasie projektowania lub możliwe jest dodawanie nowych w czasie projektowania/produkcji - takie podejście wymagałoby przechowywania wszystkich danych przez cały czas.

Cóż, jeśli znasz wszystkie swoje pytania, wydaje się, że jest to klasyczny "system bankowy", który codziennie przelicza dane.

Jak o tym myślę.

  1. Wygląda jak masz ograniczoną liczbę pokoi, ludzi, dni itp
  2. zbierać dane logowania na codzień, jedną tabelę dziennie. Tylko jedno zdarzenie, jeden wiersz bazy danych, wszystkie informacje (pola), czego potrzebujesz.
  3. Zacznij analizować dane za pomocą jakiegoś skryptu crone na "północy".
  4. Aktualizowanie statystyk dla osób, pokoi itp. Po prostu zwiększaj liczbę godzin spędzonych przez Boba w pokoju xyz itp. Wszystko, czego potrzebujesz.
  5. Jak analizowane dane są ograniczone i stosunkowo mały jak analizowane (kompres) im, system może zawierać również różne zapytania jako indeksy byłby stosunkowo niewielki itp

Można móc korzystać skalowalną mapę/zmniejszenia algorytm.

0

Nie można uniknąć przechowywania faktów atomowych w następujący sposób: (sala konferencyjna, ludzie, czas trwania, dzień), co jest prawdopodobnie słabą konsolidacją, gdy ci sami ludzie spotykają się wiele razy w tym samym pomieszczeniu tego samego dnia.Może tak się dzieje w Twoim biurze :).

Tworzenie porównywarek grupowych jest interesującym problemem, ale tak długo, jak zawsze tworzy się ciągi elementów członkowskich tak samo, prawdopodobnie można to zrobić za pomocą porównań ciągów. To jednak nie jest "normalne". Aby znormalizować, potrzebujesz tabeli relacji (wiele do wielu) i skomponuj tymczasową tabelę z zestawu zapytań, aby szybko się połączyć, lub użyj klauzuli "IN" i agregatu liczenia, aby upewnić się, że wszyscy tam są (zobaczysz co mam na myśli, kiedy go wypróbujesz).

Sądzę, że możesz uzyskać protokół z sali posiedzeń, ponieważ spotkania nie powinny się pokrywać, więc kwota będzie działać.

Aby zwiększyć wydajność, należy użyć klawiszy całkowitych do wszystkich opcji z tabelami odnośników. Usuń wartości całkowite podczas analizowania zapytania lub po prostu korzystaj ze starych dobrych połączeń, jeśli czujesz się tradycyjnie.

Tak to zrobiłbym i tak :).

Powiązane problemy