Estrutura de banco de dados NoSQL para rede social Tipo Facebook

para uma aplicação de redes sociais do tipo Facebook, é necessária uma estrutura de base de dados de alto desempenho, para armazenar dados no Firebase (NoSQL)

Dados a armazenar:

 - Userinfo (name, email etc)
 - Friends
 - Posts
 - Comments on posts.

estou confuso entre as seguintes duas estruturas DB em relação ao desempenho da consulta (se a base de dados se tornar enorme).

(Ref: C_xxx é a colecção, D_xxx é o documento)

Estrutura 1

C_AllData
    - D_UserID-1
        name: xxxx,
        email: yyy,
        friends: [UserID-3, UserID-4]
        - C_Posts
            - D_PostId-1
                Text: hhh
                Date: zzz
                - C_Comments
                    - D_CommentId-1
                        UserID: 3
                        Text: kkk
                    - D_CommentId-2
                        UserID: 4
                        Text: kkk
            - D_PostId-2
                Text: hhh
                Date: zzz
                - C_Comments
                    - D_CommentId-3
                        UserID: 3
                        Text: kkk
                    - D_CommentId-4
                        UserID: 4
                        Text: kkk
    - D_UserID-2
        name: xxxx,
        email: yyy
        friends: [UserID-5, UserID-7]
        - C_Posts
            - D_PostId-3
                Text: hhh
                Date: zzz
                - C_Comments
                    - D_CommentId-5
                        UserID: 5
                        Text: kkk
                    - D_CommentId-6
                        UserID: 7
                        Text: kkk

Estrutura 2

C_AllUsers 
    - D_UserID-1
        name: xxxx,
        email: yyy
        friends: [UserID-3, UserID-4]
    - D_UserID-2
        name: xxxx,
        email: yyy
        friends: [UserID-5, UserID-7]

C_AllPosts
    - D_PostId-1
        UserID: 1
        Text: hhh
        Date: zzz
        - C_Comments
            - D_CommentId-1
                UserID: 3
                Text: kkk
            - D_CommentId-2
                UserID: 4
                Text: kkk
    - D_PostId-3
        UserID: 2
        Text: hhh
        Date: zzz
        - C_Comments
            - D_CommentId-5
                UserID: 5
                Text: kkk
            - D_CommentId-6
                UserID: 7
                Text: kkk

Os meus desejos são o que são prós e contras das duas abordagens ?

Alguns pontos que eu poderia pensar estão abaixo, por favor corrija-me se eu estiver errado.

Estrutura 1 :

está a obter todas as mensagens de um dado utilizador, mais rápido na estrutura 1 ? Uma vez que estamos apontando para a coleção exata (AllData / {UserID} / Posts/)

Uma vez que DB inteiro está sob uma colecção, a escalabilidade não é boa ?

Estrutura 2 :

DB dividido - > melhor escalabilidade ?

Melhor desempenho ?

Melhor Desempenho ?

todos os posts sob uma colecção - > procura lenta ?


ou se você pode sugerir um modelo melhor, isso seria ótimo também

Author: kernelman, 2018-09-22

1 answers

Na base Firebase uma regra é manter os tipos de entidades separados em ramos separados. Isto é especialmente importante porque:

  1. a base de fogo carrega sempre nós completos, e
  2. uma vez que você concede a um usuário acesso de leitura a um nó, eles têm acesso a todos os dados sob esse nó.

Por exemplo, em sua primeira estrutura de dados, para carregar uma lista de amigos, você terá que carregar todos os posts de todos os amigos, e todos os comentários em todos esses posts também. São muito mais dados. do que é estritamente necessário, se tudo o que querias fazer era mostrar uma lista dos nomes dos amigos.

Na sua segunda estrutura de dados, está um passo mais perto. Como agora você pode primeiro carregar os nomes dos amigos, e depois carregar seus posts. Mas mesmo nessa estrutura você tem o mesmo problema. Se você quiser mostrar a lista de títulos de post para um amigo (ou para todos os amigos), você vai ter que carregar os posts inteiros e todos os comentários. Isso é mais uma vez muito mais dados do que é necessário para mostrar uma lista of post titles. Então você definitivamente vai querer armazenar os comentários em uma lista de topo separada também, usando a mesma chave do post para identificá-los e agrupá-los.
C_AllPosts
    - D_PostId-1
        UserID: 1
        Text: hhh
        Date: zzz
    - D_PostId-3
        UserID: 2
        Text: hhh
        Date: zzz
C_AllComments
    - D_PostId-1
        - D_CommentId-1
            UserID: 3
            Text: kkk
        - D_CommentId-2
            UserID: 4
            Text: kkk
    - D_PostId-3
        - D_CommentId-5
            UserID: 5
            Text: kkk
        - D_CommentId-6
            UserID: 7
            Text: kkk

Agora se você quiser exibir um post e seus comentários, você terá que ler dois nós. Se você fizer isso para vários posts, você vai acabar com um monte de leituras, para essencialmente executar o equivalente NoSQL de um SQL JOIN. Isto é bastante normal, é essencialmente uma adesão do lado do cliente, e não é tão lento como você pode pensar, porque a base de fogo fornece os pedidos.

Para mais uma introdução sobre este tipo de modelagem de dados, eu recomendo:

E estas respostas a perguntas anteriores:

 1
Author: Frank van Puffelen, 2018-09-22 13:25:05