2012-12-26 9 views
7

Załóżmy, że chcesz modelować określoną sytuację. Firma może mieć jedną lub więcej oddziałów. Oddziały te mają pracowników, którzy mogą pracować w innej firmie (lub nawet w dwóch różnych oddziałach tej samej firmy). To oczywiście tylko przykład.Zalecenia dotyczące schematu schematu MongoDB

Załóżmy również, że większość wyszukiwań/zapytań będzie wykonywana na kolekcjach pracowników i firm.

Pierwsze (naiwne) sposobem na to byłoby umieścić wszystko (Spółka posiada szereg branż i gałęzi mieć tablicę pracowników):

{ 
    name: "Company name", 
    // other company data 
    branches : [ 
     { 
      name: "Branch name", 
      // other branch data 
      Employees: [ 
       { 
        // employee1 data 
       }, 
       { 
        // employee data 
       }, 
      ] 
     } 
    ] 
} 

Ale to byłoby bardzo nieefektywne, gdy jeden byłby zainteresowany pobieranie informacji o pracownikach (należy znaleźć firmę, a następnie powtórzyć wyszukiwanie w każdym oddziale, aby znaleźć pracownika, który jest wymagany).

Z drugiej strony można używać referencji i naśladować RDBMS (byłaby to firma, oddział i kolekcja pracowników), ale oznaczałoby to więcej zapytań.

Trzecia opcja (do której jestem najbliżej), to posiadanie pracownika jako oddzielnej kolekcji, a następnie posiadanie zestawu odniesień do niego w Oddziałach. Ponadto, aby umożliwić szybsze zapytania typu: „pracowników z pewnych nazw, które pracują dla pewnej firmy i niektórych gałęzi”, Firma ObjectId może być przechowywany w zbiorach Pracownik:

{ 
    company_id: "some id", 
    first_name: "First name", 
    last_name: "Last name", 
    // 
} 

Tak więc, w tym przypadku, aby wyszukać wszystkie pracownicy o pewnych nazwach, którzy pracują dla pewnej firmy i pewnego oddziału, trzeba by zrobić dwie kwerendy. Pierwsze zapytanie zwróciłoby firmy spełniające "warunek firmy" (nazwa firmy i nazwa oddziału), a następnie drugie zapytanie dotyczące zbierania pracowników zwróciło wszystkich pracowników o określonej nazwie i pracujących w firmach, których identyfikatory są zwracane w pierwszym zapytaniu.

Czy zrobiłbyś to w inny sposób? Czy jest jakiś inny "zalecany" sposób na zrobienie tego? Czy dodasz jakieś ulepszenia?

Co ważniejsze, co zrobić w sytuacji, gdy te dwa zapytania zwracają zestawy wyników o małym przecięciu? Jak poprawić wydajność w takim przypadku?

Odpowiedz

4

Myślę, że w większości zmierzacie w dobrym kierunku.

Chociaż istnieją przypadki, w których denormalizacja w MongoDB nie jest zła tak jak w relacyjnej bazie danych, ale w rzeczywistości jest to słuszne, należy tu znaleźć przypadek, w którym należy użyć wielu kolekcji. Dzieje się tak dlatego, że dokumenty MongoDB mają górny limit 16 MB. Kiedy masz bardzo dużą firmę z wieloma oddziałami, które mają wielu pracowników, a pod-dokument pracownika staje się bardziej zawiły, możesz łatwo złamać ten limit.

Posiadanie referencji od pracownika do firmy to dobry pomysł. Ale powinieneś rozważyć użycie nie pola _id firmy, ale raczej nazwy firmy i nazwy oddziału, o ile możesz zagwarantować, że każda ich kombinacja będzie unikatowa w kolekcji firmy (np. Z unikalnym indeksem złożonym na tych dwóch elementach pola). Powodem jest to, że kiedy patrzysz na pracownika, zazwyczaj chcesz również znać nazwę firmy i oddziałów. Gdy masz tylko _id, będziesz musiał wykonać dodatkowe zapytania, aby uzyskać te informacje.

Powiedziałeś, że nie masz relacji 1: n między oddziałami a pracownikami, ale raczej relacji n: m.W takim przypadku poleciłbym dodać tablicę "zadań" do każdego pracownika, który zawiera obiekty z dwoma polami, company_name i company_branch (może chciałbyś dodać trzecie pole "position", które mówi, co on robi tam).

Dokumenty pracownicze będzie wtedy wyglądać tak:

{ 
    first_name: "First name", 
    last_name: "Last name", 
    // 
    assignments: [ 
     { company:"Aperture Science", branch:"R&D", position:"test subject" }, 
     { company:"Black Mesa", branch:"security", position:"leader of blue shift" } 
    ] 
} 

Zauważ, że możesz użyć siły baz schemaless tutaj: Można łatwo mają firmy, które nie tylko posiadają oddziały, ale nawet więcej poziomów hierarchii (jak departamenty i grupy) i inne, które tego nie robią.

Co jednak, gdy chcę zmienić nazwę firmy lub oddziału?

W takim przypadku należy zaktualizować każdy dokument pracownika, który odwołuje się do nazwy firmy/oddziału. Tak, nie byłby to najbardziej wydajny schemat w tej sprawie. Pamiętaj jednak, że schematy MongoDB powinny zawsze być zoptymalizowane pod kątem najczęstszych przypadków użycia. Jak myślisz, co będzie się działo częściej: a) nazwa firmy lub oddziału zostanie zmieniona lub b) ktoś chce wyszukać pracownika?

+0

Dzięki za odpowiedź. Firma, oddział i pracownik byli tylko przykładem ilustrującym problem. Lubię symulację relacji wiele do wielu z tablicą przydziałów. Użyję tego i doda tam wszystkie pola "wyszukiwane". Nie przekroczę limitu 16MB, ale myślałem o przejściu z wieloma kolekcjami - jeden dla firmy (oddział byłby w nim osadzony), a drugi dla pracownika. – kevin

Powiązane problemy