2

I come from many years working with SQL Server. I am working now on a mobile game using GameSparks as the back-end which only supports NoSQL run on Mongo.

I am creating a Computer Card Game and am trying to get my head around the best-practice for creating documents in collections which relate to other documents in a different collection.

For example, I have a "player" collection which contains the players information: email address, username, that sort of stuff.

I have a separate collection called "playerCards". This contains one document per player, similar to the "player" collection. The document here would be link-able back to the player by the playerID which is sourced from the player collection.

What's the best practice in these cases where I have a 1-1 relationship for creating the key? Should my playerCards collection have a "playerId" as the index for its own collection? OR, should playerCards have its own _id->$oid index, which is unique for itself, and have "playerId" just be an attribute on the document?

I have this pattern over and over in my design, with "playerDecks" (representing the decks the player builds), etc..

Thanks for any help!

dferraro
  • 331
  • 2
  • 3
  • 10
  • 4
    Looks like you are looking at this design from a relational database perspective. Using mongoDB just because the backend supports only that and then designing a relational schema with it, sounds like a huge technical debt on the long run. I would recommend reading: https://www.mongodb.com/blog/post/6-rules-of-thumb-for-mongodb-schema-design-part-1 and other two in the series before you start down this path. – yeaske Oct 26 '17 at 20:57
  • 2
    Embrace the race conditions and data inconsistencies. – CodesInChaos Nov 27 '17 at 21:11

2 Answers2

1

It mostly depends on the way you read or retrieve the data from your collections.

I say why not having the playerCard within player (nested)? That is given that you only retrieve playerCard along with player, and there's no use case for retrieving playerCard on its own.

If you have a use case for retrieving playerCard without knowing the player, then having playerCard and player share the key (have the same value for _id) is better. This is because when you need to retrieve playerCard for a player, you can using document ID (which is the same as player's document ID). This is as opposed to having an extra attribute and an index

BA.
  • 111
  • 2
0

Usually you do not need to put the mapping in both collections because you can use search to find a player card <-> player mapping in any document. Let's say you stored it in playerCard only, you could search for playerCard using playerId, or playerCardId and you should be able to get the document.

By putting it in two places, you are duplicating the mapping, which means that when it changes, you will have to update both documents. If you ever had one request succeed and the other one fail (despite retries etc.) then your data will be inconsistent. It's best to have one source of truth.

As part of your modeling though, you may want to consider your future use cases. Would you later on introduce a concept of a game, and have one player be part of multiple games? And would you want to maintain a history of player cards per player, etc.? Create documents in a way that you can easily expand if your potential future scenarios creep in.

Omer Iqbal
  • 3,224
  • 15
  • 22