Mam pytanie, na które od jakiegoś czasu próbuję odpowiedzieć, ale nie mogę tego rozgryźć:
Jak projektujesz lub dzielisz dokumenty CouchDB?
Weźmy na przykład post na blogu.
Pół „relacyjny” sposób na zrobienie tego polegałby na stworzeniu kilku obiektów:
- Poczta
- Użytkownik
- Komentarz
- Etykietka
- Skrawek
To ma sens. Ale próbuję użyć couchdb (z tych wszystkich powodów, że jest świetny) do modelowania tego samego i jest to niezwykle trudne.
Większość postów na blogach zawiera prosty przykład, jak to zrobić. Zasadniczo dzielą go w ten sam sposób, ale mówią, że można dodać „dowolne” właściwości do każdego dokumentu, co jest zdecydowanie miłe. Więc miałbyś coś takiego w CouchDB:
- Opublikuj (z tagami i fragmentami „pseudo” modeli w dokumencie)
- Komentarz
- Użytkownik
Niektórzy ludzie powiedzieliby nawet, że możesz wrzucić tam komentarz i użytkownika, więc masz to:
post {
id: 123412804910820
title: "My Post"
body: "Lots of Content"
html: "<p>Lots of Content</p>"
author: {
name: "Lance"
age: "23"
}
tags: ["sample", "post"]
comments {
comment {
id: 93930414809
body: "Interesting Post"
}
comment {
id: 19018301989
body: "I agree"
}
}
}
To wygląda bardzo ładnie i jest łatwe do zrozumienia. Rozumiem również, w jaki sposób można pisać widoki, które wyodrębniają tylko komentarze ze wszystkich dokumentów Post, aby umieścić je w modelach komentarzy, tak samo z użytkownikami i tagami.
Ale potem myślę: „dlaczego nie umieścić całej mojej witryny w jednym dokumencie?”:
site {
domain: "www.blog.com"
owner: "me"
pages {
page {
title: "Blog"
posts {
post {
id: 123412804910820
title: "My Post"
body: "Lots of Content"
html: "<p>Lots of Content</p>"
author: {
name: "Lance"
age: "23"
}
tags: ["sample", "post"]
comments {
comment {
id: 93930414809
body: "Interesting Post"
}
comment {
id: 19018301989
body: "I agree"
}
}
}
post {
id: 18091890192984
title: "Second Post"
...
}
}
}
}
}
Możesz łatwo tworzyć widoki, aby znaleźć to, czego szukasz.
W takim razie mam pytanie, jak określić, kiedy podzielić dokument na mniejsze, a kiedy dokonać „RELACJI” między dokumentami?
Myślę, że byłoby znacznie bardziej „zorientowane obiektowo” i łatwiej byłoby odwzorować je na Obiekty Wartości, gdyby zostały podzielone w ten sposób:
posts {
post {
id: 123412804910820
title: "My Post"
body: "Lots of Content"
html: "<p>Lots of Content</p>"
author_id: "Lance1231"
tags: ["sample", "post"]
}
}
authors {
author {
id: "Lance1231"
name: "Lance"
age: "23"
}
}
comments {
comment {
id: "comment1"
body: "Interesting Post"
post_id: 123412804910820
}
comment {
id: "comment2"
body: "I agree"
post_id: 123412804910820
}
}
... ale potem zaczyna wyglądać bardziej jak relacyjna baza danych. Często dziedziczę coś, co wygląda jak „cała witryna w dokumencie”, więc trudniej jest to modelować za pomocą relacji.
Przeczytałem wiele rzeczy o tym, jak / kiedy używać relacyjnych baz danych w porównaniu z bazami danych dokumentów, więc nie jest to główny problem. Bardziej zastanawiam się, jaką dobrą regułę / zasadę zastosować podczas modelowania danych w CouchDB.
Innym przykładem są pliki / dane XML. Niektóre dane XML są zagnieżdżone ponad 10 poziomów i chciałbym sobie wyobrazić, że używając tego samego klienta (na przykład Ajax on Rails lub Flex), wyrenderowałbym JSON z ActiveRecord, CouchRest lub dowolnego innego Object Relational Mapper. Czasami dostaję ogromne pliki XML, które stanowią całą strukturę witryny, jak ta poniżej, i musiałbym zmapować je na Obiekty Wartości, aby użyć ich w mojej aplikacji Rails, więc nie muszę pisać innego sposobu serializacji / deserializacji danych :
<pages>
<page>
<subPages>
<subPage>
<images>
<image>
<url/>
</image>
</images>
</subPage>
</subPages>
</page>
</pages>
Więc ogólne pytania CouchDB to:
- Jakich reguł / zasad używasz, aby podzielić swoje dokumenty (relacje itp.)?
- Czy można umieścić całą witrynę w jednym dokumencie?
- Jeśli tak, w jaki sposób radzisz sobie z serializacją / deserializacją dokumentów z dowolnymi poziomami głębokości (jak powyższy przykład dużego json lub przykład XML)?
- A może nie przekształcasz ich w VO, czy po prostu zdecydujesz, że „te są zbyt zagnieżdżone w Object-Relational Map, więc po prostu uzyskam do nich dostęp za pomocą surowych metod XML / JSON”?
Wielkie dzięki za pomoc, kwestia podziału danych w CouchDB była dla mnie trudna do powiedzenia „tak mam to robić od teraz”. Mam nadzieję, że wkrótce się tam dostanę.
Przestudiowałem następujące strony / projekty.
- Hierarchiczne dane w CouchDB
- CouchDB Wiki
- Sofa - CouchDB App
- CouchDB The Definitive Guide
- Screencast PeepCode CouchDB
- CouchRest
- CouchDB README
... ale nadal nie odpowiedzieli na to pytanie.