How do I find what data is in a .mbtiles file that I've created?

(a related previous question is this one from 2011)

Using Tilemaker**, I’ve created a .mbtiles file. Using a sample map I can see that the data that I’d expect to be in there is. However, can I analyse the .mbtiles file directly to see what is in it, how much space the data at each zoom level takes, what data is present at each zoom level etc.?

It’s a sqlite database, so I can dump the contents out easily enough:

sqlite3 blah.mbtiles
SQLite version 3.37.2 2022-01-06 13:25:41
Enter ".help" for usage hints.
sqlite> .output blah.txt
sqlite> .dump
sqlite> .exit

I get something like this:

PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE metadata (name text, value text, UNIQUE (name));
INSERT INTO metadata VALUES('name','SVE01');
INSERT INTO metadata VALUES('type','baselayer');
INSERT INTO metadata VALUES('version','0.1');
INSERT INTO metadata VALUES('description','SVE01 - based on Tilemaker example');
INSERT INTO metadata VALUES('format','pbf');
INSERT INTO metadata VALUES('minzoom','0');
INSERT INTO metadata VALUES('maxzoom','14');
INSERT INTO metadata VALUES('bounds','-2.567177,53.619990,-0.040615,54.702224');
INSERT INTO metadata VALUES('center','-1.303896,54.161107,7');
INSERT INTO metadata VALUES('json','{"vector_layers":[{"id":"transportation","description":"transportation",    "fields":{"class":"String","edge":"String"}},{"id":"waterway","description":"waterway","fields":{"class":"St    ring"}},{"id":"building","description":"building","fields":{}}]}');
CREATE TABLE tiles (zoom_level integer, tile_column integer, tile_row integer, tile_data blob, UNIQUE (zoom_    level, tile_column, tile_row));
INSERT INTO tiles VALUES(4,7,10,X'1f8b080000000000000303000000000000000000');
INSERT INTO tiles VALUES(3,3,5,X'1f8b080000000000000303000000000000000000');
INSERT INTO tiles VALUES(8,126,174,X'1f8b080000000000000 ... snip ... ff3fce55244eef6c0600');
...
INSERT INTO tiles VALUES(0,0,0,X'1f8b080000000000000303000000000000000000');
CREATE UNIQUE INDEX tile_index on tiles (zoom_level, tile_column, tile_row);
COMMIT;

Obviously the actual data in some of the database “fields” needs further decoding - is there anything that already exists that can report on this?

** Obviously plenty of other tools are available and my question isn’t specific just to Tilemaker.

If you don’t want to rely on the metadata fields for information about the data set, here’s a query that gives you the extent of the tiles, their number, and total size per zoom level:

SELECT zoom_level, 
    min(tile_column), max(tile_column),
    min(tile_row),max(tile_row), 
    count(*),
    sum(length(tile_data)) 
FROM tiles 
GROUP BY zoom_level;

But that’s about how far you can get in sqlite, you’d have to extract the individual MVTs and analyze them in order to find out which layers are actually present.

You can open .mbtiles in QGIS - it’s as simple as just dragging the file onto the QGIS window. Alternatively I’ll often start tilemaker-server running, then use vt2geojson to fetch a tile and decode it into GeoJSON.

you could extract the content as geojson and analyze these, e.g. with tippecanoe-decode
https://github.com/mapbox/tippecanoe