我需要一些关于我的想法的意见。如果你对 SQLite 和最低预算的高端解决方案感兴趣/有经验(现在只赢;))这是给你的。在充实这个问题时,我对这个想法感到非常兴奋,所以请耐心等待。 下面有一个 TL;DR
我用 SQLite 开发了一个 VB.NET (3.5) 桌面应用程序。数据在 EAV 模型中结构化,因为我需要这种灵活性(数据的语义结构单独存储在 XML 文件中)。该应用程序的性能实际上远远超出了我的预期,即使对于手头的场景而言,大型数据库(主文件大约 120MB)也是如此。
当 SQLite 文件位于网络文件夹中时,正如预期的那样,性能非常糟糕。这是可以忍受的,但我有更高的目标。预期场景(目前)是最大的。需要在本地 Windows 网络中同时访问数据库的 10 个用户。繁重的读取访问需要 98% 的并发,插入和更新是稀疏且小的。
该软件几乎只在预算较低且技术基础设施(支持和硬件)更低的环境中使用,因此我的目标是避免使用数据库服务器。我也不想通过 SQLitening 实现我自己的 SQLite“服务器”(即告诉应用程序的一个实例自动“共享”网络中的数据库),因为我希望数据库能够驻留在独立的网络驱动器上.
在意识到无法通过优化查询来修改这种情况后,我的第一个冲动是一种“延迟同步”方法,它几乎可以轻松实施。该数据库是“维基式”,(几乎)只有插入,因此根本不会出现任何(很多)冲突问题:“最后”出现的人获胜,每个字段都有一个带有时间戳和用户 ID 的更改历史记录,并且可以单独回滚。条目被“标记为已删除”并且可以在“清理”操作时被丢弃。尽管它的代价是永远不会“实时”地看到其他用户在会话期间更改或输入的数据,而且同步过程可能需要一段时间,用户可能会在“高峰时间”相互阻止。我们说的可能是最坏的情况几分钟,这不会
TL;DR:如何使用 SQLite 为最终用户应用程序实现实时、无服务器、本地网络共享数据库,该应用程序已经在一个场景中的本地数据文件上执行得非常好
- 许多选择
- 几个INSERT
- 没有删除和
- 每个用户会话几乎没有任何更新。
让我们进一步假设
- 总是有足够的可用硬盘空间
- 由于存档机制(和数据隐私限制),数据库永远不会超过 200MB
- 我们可以有效地判断文件是否已更改以及数据库文件所在的“共享目录”中的更改者
- 我们可以从共享目录中足够快地复制文件
现在我想到的是为每个会话实现差异文件,这些文件将在本地缓存以进行读取访问。
在客户端会话开始时:
- 检查共享目录中的大文件和特定于会话(见下文)的文件,以了解自上次会话以来的更改(共享目录中的 CRC+日志文件)
- 如果更改或未缓存,则在每个会话之前将大 (200MB) 当前数据库文件复制到本地路径
如果更改或未缓存,还复制所有特定于会话的文件(见下文)
会话期间的所有 INSERT 都被写入共享目录中的一个小的、特定于会话的文件
- 这可以限制为合适的大小,例如每个文件 2MB 或更小,然后创建一个新文件
- 然后按顺序执行读访问(SELECTs)
- 在主文件的本地副本中
- 在会话文件的本地副本中
- 在共享缓存中的所有当前(即新)会话文件中
- 在检测到新的会话文件时,会话文件将再次复制到本地缓存
- 最后,会话文件定期合并到大文件中
- 这可能是在每次会议结束时,但如果我没记错的话,可能是任何时候。
这个会
- 消除所有写并发
- 消除大文件和所有本地会话文件的读取并发
- 减少读取小型会话文件所需的并发性
- 最小化网络使用以访问最新的会话文件(每个并发用户 2MB)
- 为每个客户端保留当前数据状态的实时视图
这对我来说听起来太棒了。
问题:我正在概述这个“协议”的名称,以便我可以做进一步的研究?
您是否认为这是 SQLite 的一种可行方法,或者这是一种疯狂的追逐——我是否忽略了明显的缺点?
如果您在船上,会话文件的大小合适(n * page_size?)?
谢谢您的意见!
克里斯托夫