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

huangapple go评论122阅读模式
英文:

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

问题

设计一个包含基本信息和Markdown内容字段的表/实体,允许用户轻松创建表格等。

我想的是这样的:

  1. type Tournament struct {
  2. ID int64 `datastore:"-"`
  3. MDContent []byte `datastore:",noindex"`
  4. Name string
  5. URL string
  6. DateCreated int64
  7. CreatedBy string
  8. DateUpdated int64
  9. UpdatedBy string
  10. ApprovalStatus int64 // 0=待决定, 1=已批准, 2=已拒绝, 3=已停用
  11. ApprovalBy string
  12. }

我的问题是如何更新它。ID字段也将用作URL路径,例如,如果一个实体的ID为7,则它将显示在example.com/tournament/7。

我认为这就排除了简单地创建一个具有更新数据的新实体,然后在上一个实体上设置ApprovalStatus=3的可能性,因为如果这样做,example.com/tournament/7 URL将不再请求正确的ID。

我也不喜欢创建自己的唯一ID的想法,因为我认为利用Datastore ID生成会更好(这也使得根据URL轻松获取正确的实体);我考虑创建一个新的实体/表来跟踪修订,但我不确定所有这些是否高效,所以我希望一些专家能给予一些建议。


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

如果按照这种方式进行,我认为在TournamentEdit实体结构中需要包含一个TournamentID字段。

  1. type TournamentEdit struct {
  2. ID int64 `datastore:"-"`
  3. TournamentID int64
  4. MDContent []byte `datastore:",noindex"`
  5. DateCreated int64
  6. CreatedBy string
  7. ApprovalStatus int64 // 0=待决定, 1=已批准, 2=已拒绝, 3=已停用
  8. ApprovalBy string
  9. }

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

  1. func (db *datastoreDB) GetTournamentByKeyID(ctx context.Context, keyID int64) (*Tournament, error) {
  2. key := datastore.IDKey("Tournament", keyID, nil)
  3. var tournament Tournament
  4. err := db.client.Get(ctx, key, &tournament)
  5. // 错误检查
  6. tournament.ID = key.ID
  7. var edits []TournamentEdit
  8. query := datastore.NewQuery("TournamentEdit")
  9. query = query.Filter("TournamentID =", tournament.ID)
  10. query = query.Filter("ApprovalStatus =", 1)
  11. if _, err := db.client.GetAll(ctx, query, &edits); err != nil {
  12. // 错误检查
  13. }
  14. tournament.Edits = edits // 我猜这样做是错误的方式?
  15. return &tournament, nil
  16. }

这样可以吗?

英文:

The idea is to design a table/entity that contains some basic info, as well as a Markdown-Content field that would allow users to easily create tables and such.

I'm thinking something like this:

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

My problem is figuring out how to update it. The ID field will also be used as the URL path, e.g. if an entity has ID 7 then it will be displayed on example.com/tournament/7.

I believe this eliminates the possibility of simply creating a new entity with updated data, and then set the ApprovalStatus=3 on the previous entity, because if you do as such then the example.com/tournament/7 URL will no longer request the correct ID.

I also don't like the idea of creating my own unique ID because I think it would be great to simply take advantage of the Datastore ID generation (which also makes it easy to get the correct entity based on URL); I considered creating a new entity/table that would keep track of revisions but I'm not sure how efficient all of this is, so I was hoping some expert might be able to give some advice.


Update related to @mkopriva solution:

If you do it this way, then it's necessary to include a TournamentID field inside the TournamentEdit entity struct I think?

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

And then the retrieve function could look like this:

  1. func (db *datastoreDB) GetTournamentByKeyID(ctx context.Context, keyID int64) (*Tournament, error) {
  2. key := datastore.IDKey("Tournament", keyID, nil)
  3. var tournamnet Tournament
  4. err := db.client.Get(ctx, key, &tournament)
  5. // err checking
  6. tournament.ID = key.ID
  7. var edits TournamentEdits
  8. query := datastore.NewQuery("TournamentEdit")
  9. query = query.Filter("TournamentID =", tournament.ID)
  10. query = query.Filter("ApprovalStatus =", 1)
  11. if _, err := db.client.GetAll(ctx, query, &edits); err != nil {
  12. //err checking
  13. }
  14. tournament.Edits = edits // I guess this is wrong way to do it?
  15. return &tournament, nil
  16. }

Would this work?

答案1

得分: 1

你可以创建一个新的实体来表示比赛的“编辑”操作。顺便说一下,我不是一个“datastore”用户,所以我不确定这是否是你对实体建模的方式,但是对于大多数数据库来说,基本思路是相同的:

  1. type Tournament struct {
  2. ID int64 `datastore:"-"`
  3. MDContent []byte `datastore:",noindex"`
  4. Name string
  5. URL string
  6. DateCreated int64
  7. CreatedBy string
  8. DateUpdated int64
  9. UpdatedBy string
  10. Edits []TournamentEdit
  11. }
  12. type TournamentEdit struct {
  13. ID int64 `datastore:"-"`
  14. MDContent []byte `datastore:",noindex"`
  15. DateCreated int64
  16. CreatedBy string
  17. ApprovalStatus int64 // 0=待决定, 1=已批准, 2=已拒绝, 3=已终止
  18. ApprovalBy string
  19. }

这样你就可以在队列中拥有来自不同用户的多个编辑,对特定的编辑进行CRUD操作,并且可以根据它们的状态进行筛选。

英文:

One thing you could do is to simply create a new entity that would represent the edit of a tournament. By the way, I'm not a datastore user so I'm not sure if this is how you would model the entities but the general idea is the same for most, if not all, databases:

  1. type Tournament struct {
  2. ID in64 `datastore:"-"`
  3. MDContent []byte `datastore:",noindex"`
  4. Name string
  5. URL string
  6. DateCreated int64
  7. CreatedBy string
  8. DateUpdated int64
  9. UpdatedBy string
  10. Edits []TournamentEdit
  11. }
  12. type TournamentEdit struct {
  13. ID in64 `datastore:"-"`
  14. MDContent []byte `datastore:",noindex"`
  15. DateCreated int64
  16. CreatedBy string
  17. ApprovalStatus int64 // 0=to be decided, 1=approved, 2=rejected, 3=discontinued
  18. ApprovalBy string
  19. }

This should allow you to have multiple edits from different users in the queue, CRUD a specific edit, and or filter edits by their status.

huangapple
  • 本文由 发表于 2017年4月18日 20:45:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/43472580.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定