【问题标题】:How to structure my sport manager Firebase database如何构建我的运动经理 Firebase 数据库
【发布时间】:2017-12-13 12:46:42
【问题描述】:

我正在构建一个运动管理器应用程序,让用户可以创建自己的比赛并更新比赛结果以供其他参与者参考。

我阅读了很多关于数据库平坦度的文章(我来自 SQL :-),并看到了 Firebase 团队的许多视频教程。

此时我有这样的结构:

{sport-manager :
    ...
    groups : {
        "groupId1" : {
            competitionId : "competitionId1"
            name : "Group A",
            type : "LEAGUE"
        },
        "groupId2" : {
            competitionId : "competitionId1"
            name : "West playoofs",
            type : "PLAYOFFS"
        },
        ...
    },
    players : {
        "playerId1" : {
            birthday : 351408600000,
            firsName : "Jhon",
            lastName : "Doe",
            shirtNumber : 0,
            teamId : "teamId1"
        },
        ...
    },
    teams : {
        "teamId1" : {
            competitionId : "competitionId1"
            name : "Team 1",
            },
        ...
    },
    teamGroupStats : {
        "groupId1" : {
            "teamId1" : {
                goalsAgainst: 0,
                goalsFavor: 0,
                matchesDraw: 0,
                matchesLoss: 0,
                matchesPlayed: 0,
                matchesWin: 0,
                points: 0,
                teamName: "Team 1",
            },
            "teamId2" : {
            ...
            },
            ...
        },
        "groupId2" : {
            "teamId2" : {
            ...
            },
            ...
        }
        ...
    }
}

这种结构让我可以查询以通过这种方式使用属于组的所有团队的数据填充 ListView 适配器:

DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference();
Query groupQuery = mDatabase.child("teamGroupStats").child("groupId1")

或者当我必须从确定的球队中获得球员时:

Query playersQuery = mDatabase.child("players").orderByChild("teamId").equalTo("teamId1");

到目前为止,一切都很好。当我必须从这个结构中删除一个团队时,我的问题就来了。为了避免完整性问题,我使用多路径更新来全部删除。

  • 一支球队可以有一名或多名球员
  • 团队可以是一个或多个组的一部分。

考虑到这一点,我可以删除包含他所有球员的任何球队。

Map<String, Object> deleteMap = new HashMap<>();
deleteMap.put("teams/teamId1", null);

Query playersQuery = mDatabase.child("players").orderByChild("teamId").equalTo("teamId1");
playersQuery.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for (DataSnapshot playerSnapshot : dataSnapshot.getChildren()){
            deleteMap.put("players/" + playerSnapshot.getKey(), null);
        }

        // Delete all in one call!
        mDatabase.updateChildren(deleteMap);
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {

    }
});

如何进行查询以获取具有“teamId1”的所有路径在结构“teamGroupStats”中具有辅助键? 他这个结构好用吗?

【问题讨论】:

    标签: android firebase firebase-realtime-database nosql


    【解决方案1】:

    恕我直言,您的数据库结构非常好。关于您的问题,您无法像您所说的那样获得所有路径。你能做的就是以与添加数据相同的方式删除数据。因此,为了删除所有数据,我建议您使用此方法:

    private static void deleteTeam(String teamId) {
        Map<String, Object> map = new HashMap<>();
        map.put("/teams/" + teamId, null);
        map.put("/teamGroupStats/groupId1/" + teamId, null);
        map.put("/players/playerId1/teamId/", null);
        databaseReference.updateChildren(map);
    }
    

    更通用的方法是:

    private static void deleteTeam(String reference, String teamId) {
        Map<String, Object> map = new HashMap<>();
        map.put(reference, null);
        databaseReference.updateChildren(map);
    }
    

    如果您需要查询数据库以获取更多数据,请使用getRef() 方法获取引用并将这些值传递给第二种方法。

    您的所有数据都会被自动删除。

    希望对你有帮助。

    【讨论】:

    • 问题是我不是每支球队只有一名球员,或者一支球队只有一个小组。我不能使用你的方法,因为我不知道每个团队的球员名单或球队所属的小组,直到我对数据库进行查询(并且异步调用无济于事)跨度>
    • 在这种情况下,进行查询,找到您需要的所有数据并将该数据传递给方法。我用更通用的方法更新了我的答案。
    • 感谢您的帮助,但该通用方法不起作用。您在地图中仅填充一对“path, null”,并且不会进行多路径删除。我在帖子中显示的删除团队及其所有球员的方法很好,我的问题是从“teamGroupStats”获取辅助密钥(团队 ID)。如果做不到,可能是我的结构有问题。
    • 要拥有多路径然后只需使用地图添加所需的路径,最后只需调用databaseReference.updateChildren(map);
    【解决方案2】:

    最后我找到了一个解决方案。我修改了我的数据库以存储团队在 Team 结构中所属的所有组 ID。

    teams : {
        "teamId1" : {
            competitionId : "competitionId1"
            groups : {
                "groupId1" : true,
                "groupId6" : true,
                ...
            },
            name : "Team 1",
            },
        ...
    

    有了这些信息,我可以在 playerQuery 的监听器中添加一个内部 ValueEventListener 并进行更新/删除。

    public static void deleteTeam(final String teamId){
        Map<String, Object> deleteMap = new HashMap<>();
        deleteMap.put("teams/" + teamId, null);
    
        DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference();
        Query playersQuery = mDatabase.child("players").orderByChild("teamId").equalTo(teamId);
        playersQuery.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                for (DataSnapshot playerSnapshot : dataSnapshot.getChildren()){
                    String playerId = playerSnapshot.getKey();
                    deleteMap.put("players/" + playerId, null);
                }
    
                mDatabase.child("teams").child(teamId).child("groups")
                    .addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        for (DataSnapshot groupSnapshot : dataSnapshot.getChildren()){
                            String groupId = groupSnapshot.getKey();
                            deleteMap.put("teamGroupStats/" + groupId + "/" + teamId, null);
                        }
    
                        // Delete all in one call!
                        mDatabase.updateChildren(deleteMap);
                    }
    
                    @Override
                    public void onCancelled(DatabaseError databaseError) {
                        System.out.println("The read failed: " + databaseError.getCode());
                    }
                });
            }
    
            @Override
            public void onCancelled(DatabaseError databaseError) {
                System.out.println("The read failed: " + databaseError.getCode());
            }
        });
    }
    

    我对内部侦听器不太确定,我不得不对我的数据库结构进行一些更改,但这工作正常。

    如果有人知道这样做的更好方法,我愿意阅读。谢谢!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-20
      • 2017-10-19
      • 1970-01-01
      • 2018-01-02
      • 1970-01-01
      • 1970-01-01
      • 2018-08-02
      相关资源
      最近更新 更多