Pomysl na architekture spasionej struktury danych

Witam, mam do rozwiazania problem architektury aplikacji ktora umozliwia uzytkownikowi dodawanie i grupowanie slowek, ktorych sie uczy (w obcym jezyku np.)

Pierwszym przyblizeniem jest relacja jeden do wielu laczaca uzytkownika z rekordami zapisujacymi metadane slowka (UserWord),
z wylaczeniem danych slownikowych czyli tlumaczeniem, czesciami mowi itd.
Dane slownikowe zawieraja sie w kolekcji nosql (Word), Word embeds_many definitions.

W kazdym z rekordow relacji ze slowkami (UserWord) znajduje sie klucz obcy
odwolujacy sie do kolekcji.

Typowe uzycie zasobu wyglada mniej wiecej tak.

[code]# wyciagamy idki slowek usera
user_word_ids = User.last.user_words.map(&:word_id)

wyciagamy dane leksykalne, tlumaczenia

dict_words = Word.any_in(:word_id => user_word_ids)

prezentujemy dane

dict_words.first.value #cat
dict_words.first.definitions #kot, kotek etc.[/code]
Architektura powyzsza ssie dlatego ze:
Kontekst1: Relacja user-slowko (UserWord) jest traktowana duza iloscia updejtow, insertow, deletow, i selectow, jak rowniez strategia ich wybierania jest rozna, tj

W kontekscie listy slowek uzytkownika:

  1. raz potrzebujemy kompletnie wszystkiego
  2. raz potrzebyjemy kilku rekordow po okreslonym warunku
  3. raz potrzebujemy miec wszystko pogrupowane po jakims atrybucie UserWord.

Dlatego embedowanie User embeds_many UserWord, calkiem odpada.

Kontekst2: Kolekcja ze slownikiem (Word) ma tendencje do puchniecia, coraz wiecej danych leksykalnych, definicji etc. i ogolnie jest dosc wielka.
Zapytanie Word.any_in(:word_id => large_array) generuje super-trwajace-za-dlugo zapytanie. I to jest glownym problemem.

Kontekst3: Kolekcja ze slownikiem (Word) jest niezmienna, zawiera dane slownikowe, ktore z duzym prawodpodobienstwem mozna keszowac, tylko jaka strategia ?
Kontekst4: Relacja UserWord, puchnie jeszcze bardziej, w niedlugim czasie przyjmie kilka/nascie M rekordow a patrz. Kontekst1.

Przeczucie odpowiada ze najszybciej bedzie zostawic relacje UserWord, zoptymalizowac ja pod przyjecie sporej ilosci danych w obrebie tej tabelki, a
kolekcje ze slownikiem wrzucic do cache’u, ale tak naprawde to zamiecenie syfu pod wersalke.

Macie jakies wskazowki, pomysly, doswiadczenie w podobnych strukturach, dzieki.

pierwsze co zauważyłem:

user_word_ids = User.last.user_words.map(&:word_id)

ten kod działa tak, że pobiera ci wszystkie obiekty user_words i dopiero później mapuje je na word_id -> WNIOSEK: bardzo nieoptymalne

Co do reszty jak to zwykle bywa przy większych opisach, chciałeś dobrze a wyszło jak zawsze. Napisz jakiś konkretny przykład (na przykładach zarówno zrozumienie jak i tłumaczenie zawsze jest najprostsze), bo po opisie (w niektórych miejscach bardzo ogólnikowy) ciężko coś wymyśleć.

Masz racje moj blad, skrot myslowy. Powinno byc

[code]# wyciagamy wszystkie user_words, bo potrzebujemy je wszystkie i potrzebujemy informacje w nich zawarte.
user_words = User.last.user_words

przy okazji dociagamy sobie dane slownikowe

user_word_ids = user_words.map(&:word_id)
dictionary_words = Word.any_in(:word_id => user_word_ids)[/code]

Postaram sie naskrobac typowe use case’y. THX

[code]# wyciagamy wszystkie user_words, bo potrzebujemy je wszystkie i potrzebujemy informacje w nich zawarte.
user_words = User.last.user_words

przy okazji dociagamy sobie dane slownikowe

user_word_ids = user_words.map(&:word_id)
dictionary_words = Word.any_in(:word_id => user_word_ids)[/code]
I tak mozesz i powinienes to zalatwic na poziomie bazy, troche bardziej skomplikowany sql ale sie da spokojnie.