在 no-SQL 数据库中有效地建模关系

Modeling relations efficiently in a no-SQL database

我正在为如何在 NoSQL 数据库(如 Firestore)中建模一对多和多对多关系而苦恼。 我想为教师、学生和 Classes 建模:一个学生至少是一个 class 的一部分,一个教师可以教多个 classes。 在关系数据库中,这可能会导致下表(我根本不是数据库专家)

我希望能够执行以下查询:

但是在 NoSQL 中建模的惯用方法是什么,例如 Firestore?我读到在 NoSQL 中不可用联接,并且数据重复在 NoSQL 中并不少见,但我对数据库结构的外观感到困惑。

由于我们正在根据我们打算执行的查询构建 Firestore 数据库,因此对于以下查询:

  1. 对于给定的Class,里面有哪些学生
  2. 对于给定的教师,Classes he/she 教授
  3. 对于给定的Class,哪个老师教的

请检查以下架构:

Firestore-root
  |
  --- classes (collection)
  |     |
  |     --- $classId (document)
  |           |
  |           --- id: "classId"
  |           |
  |           --- name: "ClassName"
  |           |
  |           --- pupils (array)
  |                |
  |                --- 0: "pupilId"
  |                |
  |                --- 1: "pupilId"
  |
  --- teachers (collection)
  |     |
  |     --- $teacherId (document)
  |           |
  |           --- id: "classId"
  |           |
  |           --- name: "TeacherName"
  |           |
  |           --- phone: "+000..."
  |           |
  |           --- email: "email@gmail.com"
  |           |
  |           --- classes (array)
  |                |
  |                --- 0: "classId"
  |                |
  |                --- 1: "classId"
  |
  --- pupils (collection)
        |
        --- $pupilId (document)
              |
              --- id: "pupilId"
              |
              --- name: "PupilName"
              |
              --- teachers (array)
                   |
                   --- 0: "teacherId"
                   |
                   --- 1: "teacherId"

我将在 Java 中编写查询,但它也可以简单地翻译成其他编程语言。

考虑以下 rootRef:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();

以及以下合集参考:

CollectionReference classesRef = rootRef.collection("classes");
CollectionReference teachersRef = rootRef.collection("teachers");
CollectionReference pupilsRef = rootRef.collection("pupils");

#1。要获得存在于 class 中的学生,您必须创建对该特定 class:

的引用
DocumentReference classIdRef = classesRef.document(classId);
classIdRef.get().addOnCompleteListener(/* ... /*);

下载文档,获取"pupils"数组中存在的所有学生ID。然后为每个学生 ID,创建一个新的引用:

DocumentReference pupilIdRef = classesRef.document(pupilId);

并得到他们对应的数据

#2。同样的,我们在上面做了,在老师的情况下也这样做。从数组中获取 classes 并为每个 class 创建一个单独的数据库调用以获取相应的数据。

#3。和以前一样。