背景:
我正在开发一个SQLite平铺缓存数据库(类似于MBTiles规范),该数据库目前仅由一个表Tiles组成,其中包含以下列:
X [INTEGER] -水平平铺索引(非地图坐标)
Y [INTEGER] -垂直平铺指数(非地图坐标)
Z [INTEGER] -瓷砖的缩放级别
Data [BLOB] -具有平铺图像数据的流(当前为PNG图像)
所有的平铺计算都是在应用程序中完成的,因此带有相应TADSQLiteRTree类的TADSQLiteRTree对我来说没有任何意义。我所需要的只是尽可能快地加载由给定的Data值找到的记录的X, Y, Z字段blob流。
除此数据库外,应用程序还将具有一个内存缓存,该缓存由类似于以下TTileCache类型的哈希表实现:
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流?
你会用:
发布于 2013-05-11 00:44:44
当然要使用TADQuery。除非将查询设置为Unidirectional,否则它将缓冲内存中从数据库返回的所有记录(默认为50)。由于您正在处理blobs,所以应该编写查询以检索所需的最低记录数。
使用参数化查询,如下所示
SELECT * FROM ATable
WHERE X = :X AND Y = :Y AND Z = :Z最初打开查询后,可以更改参数,然后使用Refresh方法检索下一条记录。
无法使用内存表从数据库检索数据,必须通过查询填充数据。它可以用来替换您的TTileCache记录,但是我不推荐它,因为它比内存缓存实现有更多的开销。
发布于 2017-07-10 15:45:59
我将使用TFDQuery进行查询,如下所示。假设您要在地图上显示获取的瓷砖,您可以考虑一次为丢失的(非缓存的)瓷砖区域提取所有瓷砖,而不是为您的瓷砖网格一个接一个地抓取瓷砖:
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时间,而此时您正在从结果集中读取瓷砖,所请求的区域不在可见视图之外(您停止读取,而从未读取其他视图)。
https://stackoverflow.com/questions/16490518
复制相似问题