【问题标题】:Choosing DB model for an app similar to Notion, Block-based ("paragraphs") or document-based?为类似于 Notion、基于块(“段落”)或基于文档的应用程序选择 DB 模型?
【发布时间】:2022-02-09 02:06:22
【问题描述】:

1。问题

最近,似乎许多具有“无限”树结构的笔记管理器正在选择块模型(其中每个段落都是数据库中的一个条目),而不是文档或文件模型。

Blocks Documents
Notion
Workflowy
Remnote
Dynalist
Roam Research
Evernote
Obsidian
Bear app

如果您发现表格中有任何错误,请告诉我。

8 个月来,我们一直在开发一个与 Notion 非常相似的应用程序,同样使用块模型,但我们正在考虑进行彻底的改变并切换到文档模型。目前 MongoDB 中的块结构如下所示:

_id: "61fd3ede7f6d2cc7a53ca669"
children: Array
    0: "61fd3ee87f6d2cc7a53ca66b"
    1: "61fd3ef37f6d2cc7a53ca671"
    2: "61fd3ef77f6d2cc7a53ca673"
backlinks: Array
type: "bullet"
parentPage: Array
    _id: "61fd3ede7f6e2ccra53ca664"
    userParent: "german-jablo"
    permisionParent: "edit, comment, read"
parentParagraph: "61fd3ede7f6d2cc7a53ca668"
content: "<p>This is a paragraph</p>"
isCollapsed: false
createdAt: 2022-02-04T14:57:34.280+00:00
updatedAt: 2022-02-04T14:57:59.585+00:00

许多页面都在讨论这两种方法的差异 (example),尽管方式非常模糊,因此我们决定打开此线程以找到更科学的问题答案。

我们应用的特点

app Blocks that can be opened as documents Blocks that can collapse or expand their children
Notion Page type blocks Toggle type blocks
Workflowy All All
Evernote Documents None
Our app Page type blocks All others

我们的应用程序有两种类型的“块”。页面类型(就像在 Notion 中一样,可以插入到任何笔记中并在当前文档“内部”生成一个文档),以及其余的块,相当于 Notion 中的“切换”块类型(即它们可以折叠或展开它们的嵌套子级)。

2。我们尝试了什么

在尝试回答我们的问题(哪种数据库模型最适合我们的应用程序)时,我们意识到答案可能是“视情况而定”。也许这两种模型在不同类型的操作或情况下都有优点或缺点。这就是为什么我们制定了这个比较表来描述我们认为这两个模型的性能对于这些操作中的每一个的表现。

Operation Blocks Documents Apparent Winner
Fetch the contents of a page Find all paragraphs in the DB. Search the document in the DB. Document
Render the content of a page** Build the tree from the paragraphs recursively. You can omit the children of paragraphs whose isCollapsed property is true Render the document Document
Update the content of a paragraph in the DB Only the modified paragraph is rewritten The whole document is rewritten Block
Alternatives for rendering very large documents * Blocks can be fetched or rendered as you scroll (as Workflowy does), or as you expand child paragraphs that were collapsed. I thought that Grifds could achieve similar behavior, breaking the document into smaller chunks and bringing them in piecemeal, but it doesn't support updating an individual chunk, or even the entire document. It could also corrupt an HTML by splitting it into binary format. Block
Import or paste content In addition to converting the clipboard to HTML and/or sanitizing it, you must set up paragraphs with tree structure recursively. Note: Roam Research e.g. supports importing in JSON format, but generally users do not handle this format beforehand. Only convert the clipboard to HTML and/or sanitize the clipboard Document
Copy content** Clipboard must be sanitized and/or transformed Correct by default** Document
Real-Time Collaboration At the document level, could use some tree-based (Json) library like Automerge, or combine with some CRDT library for paragraph level. Could use tinymce solution. Tie? Both seem to have their advantages and disadvantages.

*渲染非常大的文档:大多数用户可能不会使用大于 250 kb 的笔记(考虑到多媒体文件在单独的集合中引用)。然而,在文档模型中,问题出现了:我们如何以可管理的块加载、呈现或编辑大型文档?我们提出的一个想法是将达到大尺寸的 HTML 文档拆分为以 kb 为单位的特定大小的部分,而不是将它们拆分为段落。 (它就像一种允许您部分修改文件的 Gridfs。)这是个好主意吗?

**DOM应该嵌套吗?为了能够折叠或展开嵌套的子段落,具有块模型的笔记管理器以嵌套的方式构造DOM(段落在div中,在他们的父 div 内等)。但是,文档模型中的另一种选择可能是,当用户按下 Tab 时,只有该块(HTML 标记,如 &lt;p&gt;&lt;li&gt;)被分配一个数字小于或等于 1 的属性,表示嵌套相对于前一个块的级别。这样当你按 tab 嵌套或 shift-tab 取消嵌套时,你只需要修改 HTML 元素的一个属性,而不是许多元素;并且 DOM 保持简单,没有嵌套块。

3。我们的结论

我们相信,对于比较表中的每一行,都可以进行基准测试来衡量两种模型的性能。 其他人也做过类似的herehere,比较了使用这两种模型的笔记管理器的性能。这些测试的问题在于,很难就这两种模型的优劣得出准确的结论。 Obsidian 在本地使用文档,因此您不必同步笔记。 Roam Research 是一款非常新且优化不佳的应用程序。标准笔记在本地加密笔记。换句话说,它并不总是苹果对苹果。

即使可以进行测试,我们相信答案甚至可能取决于每个用户如何使用应用程序。假设用户 A 通常使用段落嵌套(折叠或展开它们)将他的笔记组织在长文档中。另一方面,用户 B 通常通过在文档中创建新文档来组织他的笔记。基于块模型的管理器可能对用户 A 更有效,而基于文档的管理器对 B 更有效。

因此,我们试图尽可能地消除我们的疑问,但我们仍然不确定答案您认为这两种模型中的哪一种会为我们的应用程序提供更好的性能,为什么?

4。更新

我刚刚发现了一些非常有趣的信息。似乎 TinyMCE 和 CKEditor(最高版本 4),视图和模型都与基于内容可编辑的 HTML 融合。但是,CKEditor 5 切换到 MVC [source 1][source 2]

我在 TinyMCE 5、CKEditor 4 和 CKEditor 5 中粘贴了一个几 MB 的大剪贴板进行了简短的测试,而后者的速度有点慢。我希望很快能够对其他事情进行更多测试,例如拖动块或渲染大型文档。

GitHub thread about CKEditor 5's performance when working with large documents 中,一位贡献者说“它的运行速度显然比原生内容可编辑元素慢,但打字体验非常好”。

【问题讨论】:

  • 您希望在这里张贴什么?
  • 获取有关我的问题的答案、想法或信息 :)
  • 我喜欢这篇文章,但它是 100% 违反规则的。
  • 规则我已经读了好几遍了。如果您说出违反了哪条规则会更有帮助。
  • “违反规则”可能是错误陈述。 questions to avoid asking might be helpful here上的帮助部分。

标签: javascript mongodb performance ckeditor tinymce


【解决方案1】:

看来您已经完成了作业。数据库建模有时是一门艺术,而不是一门科学。我认为这两种模型,如果你把它们优化好,你可以达到很好的性能。因此,我建议您选择需要较少工作的那个。由于您已经在块模型上工作了 8 个月,这可能是您的最佳选择。

【讨论】:

    【解决方案2】:

    喜欢您对应用程序设计的彻底思考。我只是想添加一些您可能会看的建议:

    • Obsidian 正在使用混合方法。它开始基于文档,但现在支持block links 和嵌入,同时仍然超快。在您上面链接的我的基准测试中测试的所有程序中,Obsidian 是最快的。
    • 笔记工具最重要的功能之一是有效地搜索可能数以千计的笔记。我创建了一个非常简单的测试(“Spaghetti Parmesan”测试),所有基于块的方法目前都失败了。它是关于在食谱中寻找两种成分(意大利面和帕尔马干酪)。当两种成分位于不同的块中时,所有常见的基于块的应用程序最终都无法找到配方。您可以阅读更多关于此here 的信息。我还尝试在Twitter 上与一些作者进行讨论,但没有得到任何认真的结果。如果您想继续使用基于块的方法,您可能会开始设计一种搜索算法,该算法可以处理围绕块传播的搜索词(如果您还没有的话)。我试图在上面链接的线程中概述一个算法,但不确定它是否真的适用于数十万个块。

    【讨论】:

    • 感谢您的意见。我不会说 Obsidian 采用混合方法。它基于文档。只是它使用我描述的技术来复制块功能。确实它非常快,但将它与在云中同步的应用程序进行比较也是不公平的。尽管如此,在我链接的另一个比较中,它似乎并没有落后于 Notion 等应用程序。
    【解决方案3】:

    您似乎在根据更容易建模或开发的内容做出选择。

    如果您打算在这个日益拥挤的市场中竞争,您需要考虑什么会给您带来优势,以及从长远来看什么是可持续的。

    Evernote(长期用户和前雇员)面临的两个主要问题是:

    • 一个设计非常糟糕的后端,扩展成本非常高,让共享和协作成为一场噩梦(工程方面)
    • 一个过于松散的文档模型使得向编辑器添加新功能(实时协作)变得非常困难,并且即使对于简单的功能也使得协作非常挑剔(复选框通常会产生如此多的注释冲突以致无法使用)李>

    另一方面,基于块的工具通常具有非常糟糕的网络剪辑器,因为从 HTML 到块非常困难。

    解决其中一些难题!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-25
      • 2011-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多