How to deal with relationships while using mongodb

2019-08-03 08:01发布

I know, think in "denormalized way" or "nosql way".

but tell me about this simple use-case.

db.users
db.comments

some user post a comment, and i want to fetch some user data while fetching a comment. say i want to show dynamic data, like "userlevel", and static data like "username".

with the static data i will never have problems, but what about the dynamic data?

userlevel is in users collation, i need the denormalized data duplicated into comments to archieve read performance but also having the userlevel updated.

is this archiveable in some way?

1条回答
再贱就再见
2楼-- · 2019-08-03 08:15

EDIT:

Just found an answer of Brendan McAdams, guy from 10gen, who is obviously way way authoritative than me, and he recommends to embed documents.


older text:

The first one is to manually include to each comment ObjectID of user they're belong.

comment: { text : "...", 
           date: "...", 
           user: ObjectId("4b866f08234ae01d21d89604"),
           votes: 7 }

The second one, and clever way is to use DBRefs

we add extra I/O to our disk, losing performance am i right? (i'm not sure how this work internally) therefore we need to avoid linking if possible, right?

Yes - there would be one more query, but driver will do it for you - you can think of this as of kind of syntax sugar. Does it affect performance? Actually, it is depends too :) One of the reasons why Mongo so freaking fast is that it is using memory mapped files and mongo try it best to keep all of the working set (plus indexes) directly in RAM. And every 60 seconds (by default) it syncs RAM snapshot with disk based file.
When I'm saying working set, I mean things you are working with: you can have three collections - foo, bar, baz, but if you are working now only with foo and bar, they ought to be loaded into ram, while baz stays on disk abandoned. Moreover memory mapped files allow as to load only part of the collection. So if you're building something like engadget or techcrunch there is high probability that working set would be comments for the last few days and old pages will be revived way less frequently (comments would be spawned to memory on demand), so it doesn't affect performance significally.

So recap: as long as you keep working set in memory (you may think that is read/write caching), fetching of those things is superfast and one more query wouldn't be a problem. If you working with a slices of data that doesn't fit into memory, there would be speed degradation, but I don't now your circumstances -- it could be acceptable, so in both cases I tend to choose do use linking.

查看更多
登录 后发表回答