在NoSQL系统中,example每个Lesson都有很多Exercise,在插入exercise之前需要两次检查Lesson是否存在吗?

In NoSQL system, example Each Lesson has many Exercise, do we need to check the exist of Lesson twice before inserting exercise?

好的,LessonNo 是 Lesson 的 ID table & LessonNo 是 Exercise 的外键。每课有很多练习,但每个练习只属于1课。

这是gui

Text Box "Lesson No":....

Text Area "Exercise":......

Button "Insert Exercise": 

当用户点击“插入练习”时,系统会检查Lesson是否存在。如果是,那么他们将调用 insertExercise (String exercise) 方法

public boolean checkIfThisLessonNoExists(int lessonNo){
    //query from datastore
    return true or false;
}
if(checkIfThisLessonNoExists(lessonNo)){
     insertExercise (exercise);
}
public boolean insertExercise (String exercise){
    Transaction tx=datastore.beginTransaction();
    try{
       Entity e=new Entity("Exercise");
       e.setProperty("exercise",exercise);
       datastore.put(e);
       tx.commit();
    }
    catch{
    }
}

如果像上面那样,会不会有问题?

在 Google App Engine 或任何 NoSQL 系统中,没有外部约束。那么,如果我们在插入时课程被删除了怎么办???

为了解决这个问题。我们需要在 Transaction 中再次检查 lessonNo 吗?

那么,我们应该像下面那样做吗?:

  public boolean insertExercise (int lessonNo, String exercise){
        Transaction tx=datastore.beginTransaction();
        try{
           if(checkIfThisLessonNoExists(lessonNo)){
             Entity e=new Entity("Exercise");
             e.setProperty("exercise",exercise);
             datastore.put(e);
             tx.commit();
           }
           else{
                tx.rollback();
           }
        }
        catch{
        }
    }

您描述的系统无法阻止插入无效的 Exercise - Lesson 可以随时删除或以其他方式无效,因此即使您添加 checkIfThisLessonNoExists(lessonNo) 检查 insertExercise 的内部 所有这一切都会减少插入无效 Exercise 的可能性,而不消除这种可能性。

最简单的解决方案是接受您的数据存储不会 100% 一致并在查询时采取纠正措施,即在查询 Exercises 的集合时,您应该过滤掉任何 Exercise 与 non-existent Lesson 关联,并让用户知道您返回的 Exercises 列表仅对该时间戳有效,不能反映对 LessonsExercises 在稍后的时间戳中生效。 (我不建议您在执行此查询时删除无效 Exercises,因为这可能会将只读查询转换为读写查询 - 相反,安排清理过程以定期从存储中删除无效数据。)