为用户可以编辑的页面(例如 wikipedia/stackoverflow 页面)设计数据存储架构

Designing a Datastore schema for a page that users can edit (e.g. a wikipedia/stackoverflow page)

想法是设计一个 table/entity,其中包含一些基本信息,以及一个 Markdown-Content 字段,使用户可以轻松创建表格等。

我在想这样的事情:

type Tournament struct {
  ID in64 `datastore:"-"`
  MDContent []byte `datastore:",noindex"`
  Name string
  URL string
  DateCreated int64
  CreatedBy string
  DateUpdated int64
  UpdatedBy string
  ApprovalStatus int64 // 0=to be decided, 1=approved, 2=rejected, 3=discontinued
  ApprovalBy string
}

我的问题是弄清楚如何更新它。 ID 字段也将用作 URL 路径,例如如果实体的 ID 为 7,那么它将显示在示例中。com/tournament/7.

我相信这消除了简单地用更新的数据创建一个新实体,然后在前一个实体上设置 ApprovalStatus=3 的可能性,因为如果你这样做那么这个例子。com/tournament/7 URL 将不再请求正确的 ID。

我也不喜欢创建自己的唯一 ID 的想法,因为我认为简单地利用 Datastore ID 生成会很棒(这也使得根据 URL);我考虑创建一个新的 entity/table 来跟踪修订,但我不确定所有这些的效率如何,所以我希望一些专家能够提供一些建议。


与@mkopriva 解决方案相关的更新:

如果你这样做,那么我认为有必要在 TournamentEdit 实体结构中包含一个 TournamentID 字段?

type TournamentEdit struct {
    ID             in64   `datastore:"-"`
    TournamentID   int64
    MDContent      []byte `datastore:",noindex"`
    DateCreated    int64
    CreatedBy      string
    ApprovalStatus int64 // 0=to be decided, 1=approved, 2=rejected, 3=discontinued
    ApprovalBy     string
}

然后检索函数可能如下所示:

func (db *datastoreDB) GetTournamentByKeyID(ctx context.Context, keyID int64) (*Tournament, error) {
  key := datastore.IDKey("Tournament", keyID, nil)
  var tournamnet Tournament
  err := db.client.Get(ctx, key, &tournament)
  // err checking
  tournament.ID = key.ID

  var edits TournamentEdits
  query := datastore.NewQuery("TournamentEdit")
  query = query.Filter("TournamentID =", tournament.ID)
  query = query.Filter("ApprovalStatus =", 1)
  if _, err := db.client.GetAll(ctx, query, &edits); err != nil {
    //err checking
  }
  tournament.Edits = edits // I guess this is wrong way to do it?
  return &tournament, nil
}

这行得通吗?

您可以做的一件事是简单地创建一个新实体来代表锦标赛的 edit。顺便说一句,我不是 datastore 用户,所以我不确定这是否是您对实体建模的方式,但对于大多数(如果不是全部)数据库来说,总体思路是相同的:

type Tournament struct {
    ID          in64   `datastore:"-"`
    MDContent   []byte `datastore:",noindex"`
    Name        string
    URL         string
    DateCreated int64
    CreatedBy   string
    DateUpdated int64
    UpdatedBy   string
    Edits       []TournamentEdit
}

type TournamentEdit struct {
    ID             in64   `datastore:"-"`
    MDContent      []byte `datastore:",noindex"`
    DateCreated    int64
    CreatedBy      string
    ApprovalStatus int64 // 0=to be decided, 1=approved, 2=rejected, 3=discontinued
    ApprovalBy     string
}

这应该允许您在队列中拥有来自不同用户的多个编辑,CRUD 特定编辑,和/或按状态过滤编辑。