首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用MBTiles( AnyDAC,FireDAC)从SQLite表读取平铺数据(FireDAC)的最有效方法是什么?

使用MBTiles( AnyDAC,FireDAC)从SQLite表读取平铺数据(FireDAC)的最有效方法是什么?
EN

Stack Overflow用户
提问于 2013-05-10 20:42:15
回答 2查看 2.1K关注 0票数 2

背景:

我正在开发一个SQLite平铺缓存数据库(类似于MBTiles规范),该数据库目前仅由一个表Tiles组成,其中包含以下列:

X [INTEGER] -水平平铺索引(非地图坐标)

Y [INTEGER] -垂直平铺指数(非地图坐标)

Z [INTEGER] -瓷砖的缩放级别

Data [BLOB] -具有平铺图像数据的流(当前为PNG图像)

所有的平铺计算都是在应用程序中完成的,因此带有相应TADSQLiteRTree类的TADSQLiteRTree对我来说没有任何意义。我所需要的只是尽可能快地加载由给定的Data值找到的记录的X, Y, Z字段blob流。

除此数据库外,应用程序还将具有一个内存缓存,该缓存由类似于以下TTileCache类型的哈希表实现:

代码语言:javascript
复制
type
  TTileIdent = record
    X: Integer;
    Y: Integer;
    Z: Integer;
  end;    
  TTileData = TMemoryStream;    
  TTileCache = TDictionary<TTileIdent, TTileData>;

在计算X, Y, Z值时,当请求某个瓷砖时,工作流将非常简单。我将要求一个瓷砖,内存缓存(部分填补从上面的表在应用程序。启动),如果在那里找不到瓷砖,请询问数据库(即使找不到瓷砖,也可以从瓷砖服务器下载)。

问题:

您将使用哪个AnyDAC (FireDAC)组件来频繁查询SQLite表中的3个整数列值(假设100 k记录),并可选地加载已找到的blob流?

你会用:

  • 查询类型组件(我会说,执行相同准备好的查询可能是有效的,不是吗?)
  • 内存表(我担心它的大小,因为可能有几个GB存储在tiles表中,或者它是否是流的?)
  • 不一样的东西?
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-05-11 00:44:44

当然要使用TADQuery。除非将查询设置为Unidirectional,否则它将缓冲内存中从数据库返回的所有记录(默认为50)。由于您正在处理blobs,所以应该编写查询以检索所需的最低记录数。

使用参数化查询,如下所示

代码语言:javascript
复制
SELECT * FROM ATable
WHERE X = :X AND Y = :Y AND Z = :Z

最初打开查询后,可以更改参数,然后使用Refresh方法检索下一条记录。

无法使用内存表从数据库检索数据,必须通过查询填充数据。它可以用来替换您的TTileCache记录,但是我不推荐它,因为它比内存缓存实现有更多的开销。

票数 3
EN

Stack Overflow用户

发布于 2017-07-10 15:45:59

我将使用TFDQuery进行查询,如下所示。假设您要在地图上显示获取的瓷砖,您可以考虑一次为丢失的(非缓存的)瓷砖区域提取所有瓷砖,而不是为您的瓷砖网格一个接一个地抓取瓷砖:

代码语言:javascript
复制
SELECT
   X,
   Y,
   Data
FROM
   Tiles
WHERE
   (X BETWEEN :HorzMin AND :HorzMax) AND 
   (Y BETWEEN :VertMin AND :VertMax) AND 
   (Z = :Zoom)

对于上面的查询,我会考虑将fiBlobs排除在FetchOptions之外,以节省用户移动地图视图时的一些I/O时间,而此时您正在从结果集中读取瓷砖,所请求的区域不在可见视图之外(您停止读取,而从未读取其他视图)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16490518

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档