Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CodernityDB, Pure Python NoSQL database

Pykonik
January 18, 2013

CodernityDB, Pure Python NoSQL database

Jędrzej Nowak "pigmej"
CodernityDB, Pure Python NoSQL database
html version here: http://jedrzejnowak.pl/talks/Pykonik012013/

Pykonik

January 18, 2013
Tweet

More Decks by Pykonik

Other Decks in Programming

Transcript

  1. Początek ? ~ / w o r k s p

    a c e / C o d e r n i t y D B % t r e e . ├ ─ ─ d b │ └ ─ ─ _ _ i n i t _ _ . p y └ ─ ─ s e t u p . p y 1 d i r e c t o r y , 2 f i l e s
  2. Teraz ? + docs + CodernityDB-PyClient + CodernityDB-HTTP ~ /

    w o r k s p a c e / C o d e r n i t y D B % t r e e . ├ ─ ─ C o d e r n i t y D B [ . . . ] 4 d i r e c t o r i e s , 4 5 f i l e s ~ / w o r k s p a c e / C o d e r n i t y D B % s l o c c o u n t * * / * . p y [ . . . ] T o t a l P h y s i c a l S o u r c e L i n e s o f C o d e ( S L O C ) = 9 , 2 7 8
  3. Proces testowy #1 1. Repozytorium HG 2. Jenkins master CI

    3. Tox 1. CPython2.6 2. CPython2.7 3. PyPy1.8 4. PyPy1.9 5. PyPy-dev
  4. Proces testowy #2 Developer → HG → Jenkins → Tox

    → Sukces ... lub nie Jenkins → powiadomienie via Jabber → FIX
  5. CodernityDB design Database Never overwrite ACID (no forced f s

    y n c ) Index Jeden główny i d indeks Wiele dodatkowych indeksów Storage m a r s h a l do zapisywania obiektów Łatwość implementacji alternatywnych storage (np szyfrowanych)
  6. Dataflow - get Get jest wykonywany prosto z indeksu. Brak

    spowolnienia związanego z ilością indeksów
  7. Dataflow - insert Liniowo do każdego indeksu po kolei _

    i d = s e l f . _ i n s e r t _ i d _ i n d e x ( _ r e v , d a t a ) f o r i n d e x i n s e l f . i n d e x e s [ 1 : ] : s e l f . _ s i n g l e _ i n s e r t _ i n d e x ( i n d e x , d a t a , _ i d )
  8. Dataflow - update Tak samo jak insert Delete jest tożsame

    _ i d = s e l f . _ i n s e r t _ i d _ i n d e x ( _ r e v , d a t a ) f o r i n d e x i n s e l f . i n d e x e s [ 1 : ] : s e l f . _ s i n g l e _ u p d a t e _ i n d e x ( i n d e x , d a t a , _ i d )
  9. Szybkość blisko 100 000 operacji insert / aktualizacji na sekundę

    ponad 100 000 operacji pobierania na sekundę testy wydajnościowe
  10. CodernityDB Index CodernityDB Index != SQL index Pobieranie określonych danych

    Sortowanie danych Odseparowanie danych od siebie (tabele / kolekcje)
  11. Przykład c l a s s W i t h

    X I n d e x ( H a s h I n d e x ) : d e f _ _ i n i t _ _ ( s e l f , * a r g s , * * k w a r g s ) : k w a r g s [ ' k e y _ f o r m a t ' ] = ' I ' s u p e r ( W i t h X I n d e x , s e l f ) . _ _ i n i t _ _ ( * a r g s , * * k w a r g s ) d e f m a k e _ k e y _ v a l u e ( s e l f , d a t a ) : a _ v a l = d a t a . g e t ( " x " ) i f a _ v a l i s n o t N o n e : r e t u r n a _ v a l , N o n e r e t u r n N o n e d e f m a k e _ k e y ( s e l f , k e y ) : r e t u r n k e y
  12. Nadal za trudne ? Łatwe, prawda? n a m e

    : w i t h _ x t y p e : H a s h I n d e x k e y _ f o r m a t : I m a k e _ k e y _ v a l u e : x , N o n e
  13. Jak użyć tego indeksu ? d b = D a

    t a b a s e ( ' / t m p / b ' ) d b . c r e a t e ( ) d b . a d d _ i n d e x ( W i t h X I n d e x ( d b . p a t h , ' w i t h _ x ' ) ) / / d b . a d d _ i n d e x ( s 1 ) # i f s 1 i s t h e " s i m p l e c o d e " f o r x i n x r a n g e ( 1 0 ) : d b . i n s e r t ( d i c t ( x = x ) ) f o r c u r r i n d b . a l l ( ' w i t h _ x ' ) : p r i n t c u r r
  14. Jak zacząć ? f r o m C o d

    e r n i t y D B . d a t a b a s e i m p o r t D a t a b a s e d b = D a t a b a s e ( ' / t m p / a ' ) d b . c r e a t e ( ) f o r x i n x r a n g e ( 1 0 ) : d b . i n s e r t ( d i c t ( x = x ) ) f o r c u r r i n d b . a l l ( ' i d ' ) : p r i n t c u r r
  15. Tabele / kolekcje ? Po prostu użyj indeksów! c l

    a s s T 1 I n d e x ( H a s h I n d e x ) : d e f _ _ i n i t _ _ ( s e l f , * a r g s , * * k w a r g s ) : k w a r g s [ ' k e y _ f o r m a t ' ] = ' I ' d e f m a k e _ k e y _ v a l u e ( s e l f , d a t a ) : i f d a t a . g e t ( ' t ' ) = = ' t 1 ' : r e t u r n d a t a [ ' x ' ] , N o n e d e f m a k e _ k e y ( s e l f , k e y ) : r e t u r n k e y
  16. Co teraz ? . . . d b . a

    d d ( T 1 I n d e x ( d b . p a t h , ' t 1 ' ) ) d b . a d d ( t 2 ) # c o d e f o r t = ' t 2 ' f o r x i n x r a n g e ( 1 0 ) : d b . i n s e r t ( d i c t ( t = ' t 1 ' , x = x ) ) f o r a i n x r a n g e ( 1 0 ) : d b . i n s e r t ( d i c t ( t = ' t 2 ' , a = a ) ) f o r c u r r i n d b . a l l ( ' t 1 ' ) : p r i n t c u r r # j u s t r e s u l t s f o r t = t 1 f o r c u r r i n d b . a l l ( ' t 2 ' ) : p r i n t c u r r # j u s t r e s u l t s f o r t = t 2
  17. key, value ? Dlaczego m a k e _ k

    e y _ v a l u e zwraca 2 wartości ? d e f m a k e _ k e y _ v a l u e ( s e l f , d a t a ) : r e t u r n d a t a . g e t ( ' a ' ) , { v : d a t a . g e t ( ' v ' , 0 ) * 1 0 } # . . .
  18. All... Tylko all ? Oczywiście, że nie ;-) g e

    t g e t _ m a n y get_between a l l Nadal mało ?
  19. Funkcje po stronie bazy Możesz napisać dowolną funkcję która uruchomi

    się wewnątrz bazy danych. c l a s s W i t h X I n d e x ( T r e e B a s e d I n d e x ) : # t h e r e s t o f i n d e x c o d e d e f r u n _ a v g ( s e l f , d b , s t a r t , e n d ) : l = [ ] g e n = d b . g e t _ m a n y ( ' x ' , s t a r t = s t a r t , e n d = e n d , l i m i t = - 1 ) f o r c u r r i n g e n : l . a p p e n d ( c u r r [ ' v a l u e ' ] ) r e t u r n s u m ( l ) / l e n ( l )
  20. Jak jej używać ? I to wszystko p r i

    n t d b . r u n ( ' x ' , ' a v g ' , s t a r t = 1 0 , e n d = 3 0 )
  21. Tylko HashIndex ? Moment... HashIndex nie zachowuje kolejności... c l

    a s s S I n d e x ( T r e e B a s e d I n d e x ) : d e f _ _ i n i t _ _ ( s e l f , * a r g s , * * k w a r g s ) : k w a r g s [ ' k e y _ f o r m a t ' ] = ' I ' s u p e r ( S I n d e x , s e l f ) . _ _ i n i t _ _ ( * a r g s , * * k w a r g s ) d e f m a k e _ k e y _ v a l u e ( s e l f , d a t a ) : a _ v a l = d a t a . g e t ( " x " ) i f a _ v a l i s n o t N o n e : r e t u r n a _ v a l , N o n e r e t u r n N o n e d e f m a k e _ k e y ( s e l f , k e y ) : r e t u r n k e y
  22. Znowu uproszczony n a m e : t r e

    e t y p e : T r e e B a s e d I n d e x k e y _ f o r m a t : I m a k e _ k e y _ v a l u e : x , N o n e
  23. Użycie d b = D a t a b a

    s e ( ' / t m p / f ' ) d b . c r e a t e ( ) d b . a d d _ i n d e x ( s 3 ) f o r x i n x r a n g e ( 1 0 ) : d b . i n s e r t ( d i c t ( x = x , t = ' t 1 ' ) ) f o r c u r r i n d b . a l l ( ' t r e e ' ) : p r i n t c u r r # Y a Y s o r t e d d a t a !
  24. Infix/suffix/prefix search n a m e : i n f

    i x t y p e : M u l t i T r e e B a s e d I n d e x k e y _ f o r m a t : 5 s m a k e _ k e y _ v a l u e : i n f i x ( a , 0 , 2 0 , 5 ) , N o n e m a k e _ k e y : f i x _ r ( k e y , 5 ) http://goo.gl/7b3ZM
  25. Sharding Więcej c l a s s C u s

    t o m I d S h a r d e d ( S h a r d e d U n i q u e H a s h I n d e x ) : c u s t o m _ h e a d e r = ' f r o m C o d e r n i t y D B . s h a r d e d _ h a s h i m p o r t S h a r d e d U n i q u e H a s h I n d e x ' d e f _ _ i n i t _ _ ( s e l f , * a r g s , * * k w a r g s ) : k w a r g s [ ' s h _ n u m s ' ] = 1 0 s u p e r ( C u s t o m I d S h a r d e d , s e l f ) . _ _ i n i t _ _ ( * a r g s , * * k w a r g s ) y = ' y ' * 1 5 0 0 d b = D a t a b a s e ( ' / t m p / s h a r d ' ) d b . c r e a t e ( w i t h _ i d _ i n d e x = F a l s e ) d b . a d d _ i n d e x ( C u s t o m I d S h a r d e d ( d b . p a t h , ' i d ' ) ) f o r x i n x r a n g e ( 1 0 * * 8 ) : d b . i n s e r t ( { ' x ' : x , ' y ' : y } ) http://goo.gl/nvRfJ
  26. CodernityDB-PyClient To jest jedyna różnica. p i g m e

    j @ l a p / t m p % d i f f d b _ p y . p y d b _ p y c . p y 3 a 4 , 6 > f r o m C o d e r n i t y D B P y C l i e n t i m p o r t c l i e n t > c l i e n t . s e t u p ( ) >
  27. Dziękuję za uwagę “ Nothing is impossible, it's just require

    to write "some" python. ” Codernity Labs CodernityDB