2

バックグラウンド:

私は SQLite タイル キャッシュ データベース (仕様と同様) に取り組んでおり、現在は次の列を持つMBTiles単一のテーブルから構成されています。Tiles

X [INTEGER]- 水平タイル インデックス (地図座標ではない)
Y [INTEGER]- 垂直タイル インデックス (地図座標ではない)
Z [INTEGER]- タイルのズーム レベル
Data [BLOB]- タイル画像データ (現在は PNG 画像) を含むストリーム

タイル計算へのすべての座標はアプリケーションで行われるためSQLite R*Tree Module、対応するTADSQLiteRTreeクラスの は私には意味がありません。Data必要なのは、指定された値で見つかったレコードのフィールド BLOB ストリームをX, Y, Zできるだけ速くロードすることだけです。

アプリケーションには、このデータベースを除いて、次のようなハッシュ テーブルによって実装されるメモリ キャッシュもありますTTileCache

type
  TTileIdent = record
    X: Integer;
    Y: Integer;
    Z: Integer;
  end;    
  TTileData = TMemoryStream;    
  TTileCache = TDictionary<TTileIdent, TTileData>;

X, Y, Z値を計算しながら特定のタイルを要求する場合のワークフローは単純になります。メモリ キャッシュのタイルを要求します (アプリの起動時に上記の表から部分的に埋められます)。そこでタイルが見つからない場合は、データベースに要求します (タイルが見つからない場合でも、ダウンロードします)。タイル サーバーから)。

質問:

見つかったブロブ ストリームのオプションの読み込みを使用して、SQLite テーブル (たとえば、100k レコード) 内の 3 つの整数列値を頻繁にクエリするために、どの AnyDAC (FireDAC) コンポーネントを使用しますか?

使用しますか:

  • クエリ型コンポーネント (準備された同じクエリを実行すると効率的かもしれませんよね?)
  • メモリテーブル(タイルテーブルに数GBが保存されている可能性があるため、サイズが心配です。または、たとえば何らかの方法でストリーミングされますか?)
  • 何か違います ?
4

2 に答える 2

3

必ず使用してTADQueryください。クエリを に設定しない限りUnidirectional、データベースから返されたすべてのレコードがメモリにバッファリングされます (デフォルトは 50)。ブロブを扱っているため、必要最小限のレコード数を取得するようにクエリを作成する必要があります。

次のクエリのように、パラメータ化されたクエリを使用します

SELECT * FROM ATable
WHERE X = :X AND Y = :Y AND Z = :Z

クエリを最初に開いたら、パラメーターを変更し、Refreshメソッドを使用して次のレコードを取得できます。

メモリ テーブルを使用してデータベースからデータを取得することはできませんでした。クエリを使用して値を設定する必要があります。レコードを置き換えるために使用できますTTileCacheが、メモリ キャッシュの実装よりもオーバーヘッドが大きくなるため、お勧めしません。

于 2013-05-11T00:44:44.887 に答える