Database schema

Two network-wide tables on the base prefix ({base_prefix}lh_bsa_summary and {base_prefix}lh_bsa_usage, both names filterable), scoped per site by blog_id. Created and upgraded with dbDelta on init whenever the network option lh_block_and_shortcode_auditor_db_version differs from the code’s schema version (currently 1). Both are dropped on uninstall; everything in them can be regenerated by rescanning.

lh_bsa_summary

One row per site, tag type and tag: every registered tag plus every used tag that is not registered. Rewritten as a whole on each registry capture or count refresh.

ColumnTypeNotes
idbigint unsignedPrimary key
blog_idbigint unsignedSite
tag_typevarchar(20)block or shortcode
tagvarchar(191)Block name or shortcode tag
is_registeredtinyint(1)1 if registered at the last capture
providervarchar(191)plugin:slug, theme:slug, core, namespace:name or empty
usage_countbigint unsignedTotal occurrences in content
object_countbigint unsignedPosts or widgets using it
scanned_atdatetime, GMTWhen the row was written

Keys: unique blog_tag (blog_id, tag_type, tag); blog_registered (blog_id, is_registered).

lh_bsa_usage

One row per site, object, tag type and tag. Keyed by tag type, not registration state, so a registry change only needs the summary rebuilt, never a content rescan. Rows for one object are deleted and reinserted on each scan; rows not rewritten during a full sweep are removed when it finishes.

ColumnTypeNotes
idbigint unsignedPrimary key
blog_idbigint unsignedSite
tag_typevarchar(20)block or shortcode
tagvarchar(191)Block name or shortcode tag
object_typevarchar(20)post, or widget_{id_base}
object_idbigint unsignedPost ID or widget number
object_subtypevarchar(64)Post type or widget id_base
object_statusvarchar(20)Post status; empty for widgets
occurrencesint unsignedUses in that object
scanned_atdatetime, GMTWhen the row was written

Keys: unique object_tag (blog_id, object_type, object_id, tag_type, tag); blog_tag (blog_id, tag_type, tag).

Per-site options and transients

All are removed per site on uninstall, along with the plugin’s jobs in both Action Scheduler and WP-Cron.