【问题标题】:Update list view with changes in a table使用表中的更改更新列表视图
【发布时间】:2009-05-08 09:55:55
【问题描述】:

我有一个包含大量日志消息的 SQLite 数据库。

我想在列表视图中显示它(使用 wxWidgets)。

用户可以对列表重新排序(通过按列标题),对结果集应用过滤器,并使用滚动条像通常的列表一样浏览它。用户还可以在列表中选择一个或多个条目并删除它们。

我有一个虚拟列表模型:列表视图向模型询问特定行的内容。模型使用当前过滤条件和顺序发出选择查询,并从结果中返回相应的行。

为了使其更快,我保留了结果的页面缓存:当请求一行时,我使用 LIMIT 和 OFFSET 获取整个页面(约 100 行)并从页面返回特定行。我存储了许多页面,下次请求一行时,我首先查看它是否在其中一个缓存页面中可用。事实证明,即使有 很多 个条目 (50k+),这种技术也能快速响应。

问题

我的问题是如何处理更新/插入/删除。我每个都有一个触发器,因此每当发生插入/更新/删除时都会通知模型。触发器还会告诉模型受影响条目的 ID(主键)。

我的第一个版本只是在每次触发后完全重置模型。这不是很快,但足够快。问题是,如果用户选择了一行或几行,选择就会丢失。

模型的基类 (wxDataViewVirtualListModel) 包含在发生更改时应调用的方法:

  • RowInserted(行)
  • RowDeleted(行)
  • RowChanged(行)

如果我使用它们,选择问题将得到解决,但是有问题:

  • 我如何知道更改的行是否在当前过滤集中?
  • 我如何知道列表视图中的哪一行受到了影响?

第一个问题可以通过创建一个检查条目是否属于集合的方法来解决。它的行为必须与 SQL 条件完全相同,但它是可行的。

第二个问题我根本不知道如何解决。

我使用了一个虚假的(0 或最后一行)行号来强制更新视图,但问题是如果在选择之前插入/删除了行,则选择之后指向错误的行,并且以此类推。

你会怎么做?在内存中保留包含所有条目的高级数据结构?

这个问题与另一个问题有关: Display large result set

【问题讨论】:

    标签: sqlite list listview wxwidgets


    【解决方案1】:

    我将围绕两个不同的 SELECT 操作进行设计,一个只获取所有行的主键和时间戳(INSERT / UPDATE),另一个获取单页行的所有数据。在现代机器上,将主键和时间戳的完整列表保存在内存中,即使是 100000 行也不成问题。

    每当过滤条件更改或触发触发器时,我都会再次检索主键和时间戳列表。该模型维护一个主键和匹配时间戳的列表,模型与新列表之间的比较显示需要插入、无效或删除哪些行。时间戳已更改的缓存行将从缓存中删除,具有相同时间戳的缓存行无需再次检索。当缓存过大时,将删除最旧的缓存条目。

    列表的选择可以通过其主键值来识别,因此除非该行已被删除,否则始终可以在更改模型后重新选择它,即使它现在处于完全不同的位置。我发现这比在排序更改时保持相同的行位置更直观,因为它选择了完全不同的行。

    编辑:

    这适用于来自其他数据库客户端的并发数据更改,我已经为使用 Firebird 数据库服务器的应用程序实现了这种方式。如果无法从外部更改数据,则可能不需要始终检索主键和时间戳的完整列表。

    【讨论】:

    • 谢谢。我会做这样的事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多