SQL baze podataka - Sponzor: Baze-Podataka.net MySQL, MSSQL, Oracle, Access, ODBC. Ako imate problem brže i preciznije ćete dobiti odgovor ako priložite strukturu tabela ili skript koji kreira tabele i puni ih test podacima umesto što to problem opisujete samo rečima. Sponzor: Baze-Podataka.net - Blog o bazama podataka |
|
Alati teme | Način prikaza |
|
24. 05. 2012. | #1 |
profesionalac
Qualified
Datum učlanjenja: 21.06.2007
Poruke: 166
Hvala: 27
42 "Hvala" u 23 poruka
|
ORM za no-sql baze mislim da se zove ODM (Object Document Mapper).
Potpuno mi je jasno da se trebaju u client kodu mapirati "definicije" baze (kolekcija i dokumenata). Kako radim sa custom napravljenim ORM alatom (koji je godinama peglan), upravo iz tih definicija se izvlace podaci za validaciju, za castovanje podataka na relaciji db-code, te za data migracije i za jos x stvari. Tako da mi je ideja kada i ako dodje do same implementacije, da se isti pristup primeni i za mongo ili neku drugu document bazu. Za PHP postoji Doctrine ODM.
__________________
|
"Hvala" _korso_ za poruku: |
24. 05. 2012. | #2 |
xippster
Master
Datum učlanjenja: 16.06.2005
Lokacija: Beograd
Poruke: 681
Hvala: 102
138 "Hvala" u 84 poruka
|
|
24. 05. 2012. | #3 |
član
Certified
Datum učlanjenja: 03.10.2006
Poruke: 96
Hvala: 27
44 "Hvala" u 26 poruka
|
Naravno da postoje razni gotovi mapperi ali svaka dodatna biblioteka u projektu zna da ima i svoju cenu. ODM-i nisu teski i mogu biti zabavni za pisanje, posebno ako ti za tvoje potrebe ne treba sva masinerija koju nude OSS resenja.
Posto sam obecao primer evo ga za python. Primer je vrlo jednostavan mada ovo sve moze mnogo vise da se zakomplikuje. Dakle osnovna klasa i globalno mesto gde se registruju modeli i verzije bi bili u modulu koji bi izgledao otprilike ovako: Kôd:
from pymongo import Connection version_reg = {} #"Globalni" dict koji cuve verzije def register_version_model(cls, version): """Registruj klasu koja je model za odredjenu verziju scheme""" version_reg[version] = cls def get_version_by_model(cls): """Vrati za koju verziju scheme je registrovana klasa""" for v, c in version_reg.iteritems(): if c is cls: return v return None class MongoBaseModel(object): """Klasa koju svi mongo modeli nasledjuju, i redefinisu potrebne metode""" _db = 'test_db' _collection = 'test_col' def _to_dict(self): """ Ova metoda mora da se redefinise - ona ustvari sadrzi logiku predstave modela u bazi. """ raise NotImplementedError def save(self): #Napravi od sebe dict d = self._to_dict() #vidi gde si registrovan, i zapisi to u bazu d['version'] = get_version_by_model(self.__class__) Connection()[self._db][self._collection].insert(d) @classmethod def read(cls, spec): """ Metoda procita dokument ako postoji, i na osnovu verzije konstruise objekat i vrati ga """ doc = Connection()[self._db][self._collection].find_one(spec) if doc: model_cls = version_reg.get(doc['version'], None) if not model_cls: raise ValueError("No model registered for this version") return model_cls(doc) return None Kôd:
class Calculation(MongoBaseModel) """Zamisljena klasa kalkulacije ciji se rez cuva u bazu""" def __init__(self, doc): self.date = doc['date'] self.result = doc['result'] def _to_dict(self): """Obrnuto od konstruktora - u ovom primeru nezanimljivo""" return dict( date = self.date result = self.result ) Kôd:
register_version_model(Calculation, 1) Kôd:
class NewCalculation(MongoBaseModel) """Nova klasa kalkulacije koja sada cuva i koliko je kalc trajala""" def __init__(self, doc): self.date = doc['date'] self.result = doc['result'] self.duration = doc['duration'] def _to_dict(self): """Obrnuto od konstruktora - u ovom primeru nezanimljivo""" return dict( date = self.date result = self.result duration = self.duration ) register_version_model(NewCalculation, 2) Kao sto sam rekao moze ovo mnogo vise da se zakomplikuje i nabudzi (metaprogramiranjem i slicnim cakama), naravno fale provere gresaka itd. ali funkcionalni, mali i lagani ODM ne trazi mnogo vise od ovih 30ak linija u Pythonu, bez da se patis sa nekim bloat-om sa github-a. Ako nekome neka python-specific caka nije jasna (mada ih bas i nema u gornjem kodu) rado cu pojasniti. Poslednja izmena od djipko : 24. 05. 2012. u 20:17. |
"Hvala" djipko za poruku: |
27. 05. 2012. | #4 |
profesionalac
Qualified
Datum učlanjenja: 21.06.2007
Poruke: 166
Hvala: 27
42 "Hvala" u 23 poruka
|
^ Hvala puno na trudu i primeru.
Primer je u sustini jasan, posto ima i inline komentara. Mada moze se kao sto kazes zakomplikovati, sto validacijom, sto meta definicijama, a sto jos nekim apstrakcijama. Sto vise automatizma i magicnih stvari to ce biti i kompleksnija implementacija. Imao bih samo jos 2 pitanja, posto vidim da imas iskustva sa MongoDB-om. Kako se sajt ili app (ne znam da li je jedna ili vise koje si radio) ponasaju ukoliko ima malo veceg opterecenja istih - npr. par stotina konkurentnih zahteva u sec? Najvise mislim na race-conditions posto koliko sam shvatio, MongoDB zakljucava celu bazu dok se za jednog korisnika obradjuju podaci? Da li si naisao na jos neke da kazem "klopke" kojih nema u RDBMS svetu. Jedan od primera je ovo verziranje polja. Drugi... video sam na par mesta kada se prave polja u bazi, da samo ime zauzima resurse baze. Ako imas 1000 korisnika u kolekciji users, "username" polje se 1000x pamti, da tako kazem. Pa onda radi optimizacije i performansi npr. mapiraju ga u "usn", pa ga onda "remairaju" u username u samom server/client kodu. Na ovaj nacin (procitah pre neki dan, ne secam se gde) neko je bazu sa 700MB, smanjio na 300MB, sto je vise nego pola.
__________________
|
27. 05. 2012. | #5 |
član
Certified
Datum učlanjenja: 03.10.2006
Poruke: 96
Hvala: 27
44 "Hvala" u 26 poruka
|
Nema na cemu
Sto se tice prostora - moj primer je tu uzasno neefikasan jer za SVAKI record cuva verziju. Ovo je nesto sto bi radio u pocetku razvoja, kada postoji velika mogucnost da ces imati izmena same scheme, ili ako ne maris previse za prostor (Mongo je inace vrlo "bahat" sto se prostora na disku tice, barem sa default parametrima, a i ne zaboravimo da po defaultu dodaje svoj _id na svaki record, tako da ako ti je prostor problem - sigurno moze bolje od onoga sto mongo radi po defaultu). Sto se lockovanja tice, mislim da to zavisi od tvog deployment-a. Mongo nije MySQL i sfere u kojima se oni koriste nisu skroz disjunktne, ali se i ne preklapaju u potpunosti. Opisacu ti ukratko kako ga mi koristimo, ali po meni svaki slucaj je drugaciji. Ako mene pitas nakon nekog vremena sam poceo da razmisljam da je Mongo u klasi sa Memecahced-om (samo nabudzen) bre nego sa raznim RDBMS-ovima. Dakle: mi koristimo ReplicaSet opciju gde imamo master u koji se pise (to ne rade web workeri, nego za to koristimo taskove - za queue inace isto koristimo mongo ali to je nevezano za celu pricu). Front end web serveri imaju svaki svoj mongo koji replicira mastera, i u te mongo-e se nikad ne pise (osim replikacije naravno ali je ona jako brza) vec samo cita iz njih. Dakle lag replikacije postoji (otud ona rec 'eventual' u frazi 'eventual consistency'), ali je nama nebitan, dakle kao sto rekoh zavisi od aplikacije (mi imamo peakove sa nekoliko stotina upisa, ali realnost je par desetina u sekundi). Sami upisi na mastera su uzasno brzi - ali kad kazem uzasno mislim jako uzasno, hiljade u sekundi, pre ce ti algoritam biti bottleneck nego Mongo. Ovo sve sto sam ti opisao sa ops strane nije trivijalno, ali nije ni nocna mora (Mongo ReplicaSet nije bas jednostavan za koriscenje, srusio nam je sajt 2 puta dok nismo provalili kako bezbolno da dodajemo servere, ali se sve zavrsilo na fabric skripti od par stotina linija koja to sada vrlo bezbolno radi). Sto kazu ono TL;DR: Mongo je okej sistem, ima svoje mracne strane, ali u definitivno vise nego pristojan. Sve zavisi od tvoje aplikacije, ali kad razmisljas o tome gde da ga koristis (a i vecinu nosql resenja), pre razmisljaj: memcached sa vise opcija a slabijim performansama (isto pogledaj i Redis), nego felksibilniji MySQL. PS. Nije bas tako strasno sto zakljucava celu bazu - pogledaj http://www.mongodb.org/display/DOCS/...ncurrency+work ali ako ti je to problem mozda ti treba redizajn . |
"Hvala" djipko za poruku: |
28. 05. 2012. | #6 |
profesionalac
Qualified
Datum učlanjenja: 21.06.2007
Poruke: 166
Hvala: 27
42 "Hvala" u 23 poruka
|
Prostor na disku nije problem, mada bez obzira na to nismo za rasipanje resursima.
Inace Redis ce verovatno biti u stacku posto nam je potreban pub-sub za real-time. Pa su sada varijante, nosql ili Mysql, gde bi one stvari koje su usko grlo, ako je nosql isle manje u Redis (posto pomenuh da je vec skoro izvesno clan stacka i da moze da radi i kao Memcache), ili ako je Mysql onda bi vise stvari imalo neki vid predstavljanja u Redisu. Sustina je da posto ce biti dosta sadrzaja u vidu agregacije da tako kazem, da ubrzamo i sprecimo masivno pisanje JOIN-ova nad x tabela. Trenutno nemamo bazu, pa mi je jedan od ciljeva da sada ako moze identifikujemo stvari kojih se treba paziti ili obratiti vecu paznju ako radimo sa MongoDB-om (slicno sto si pomenuo da ti niko nije rekao da treba verzirati polja). U svakom slucaju, jos jednom ti hvala puno na trudu i vremenu. Imao bih jos par pitanja, ali neka budu ovo za sada. Dosta si mi pomogao i ovako .
__________________
|
|
|