sql/tables.json.
The abstract schema format
Each table is described as a JSON object with aname, an optional comment, a list of columns, a list of indexes, and a pk array naming the primary key columns.
Column types are chosen from a fixed enum of abstract types that map to native types on each backend:
| Abstract type | MySQL | PostgreSQL | SQLite |
|---|---|---|---|
integer | INT | INTEGER | INTEGER |
bigint | BIGINT | BIGINT | INTEGER |
binary | VARBINARY(n) | BYTEA | BLOB |
blob | BLOB | BYTEA | BLOB |
text | TEXT | TEXT | TEXT |
mwtimestamp | VARBINARY(14) | TIMESTAMPTZ | BLOB |
mwtinyint | TINYINT | SMALLINT | INTEGER |
mwenum | ENUM(...) | TEXT | TEXT |
float | FLOAT | FLOAT | REAL |
Column options
| Option | Type | Description |
|---|---|---|
notnull | boolean | Whether the column is NOT NULL. Defaults to true. |
autoincrement | boolean | Auto-incrementing primary key. Defaults to false. |
default | string | number | null | Default value for the column. |
length | number | Maximum length for variable-length types. |
unsigned | boolean | Unsigned integer. Defaults to false. |
fixed | boolean | Fixed-length binary/string column. |
PlatformOptions.allowInfinite | boolean | Allow 'infinity' as a timestamp value. |
PlatformOptions.enum_values | array | Values for mwenum columns. |
PlatformOptions.doublePrecision | boolean | Use double precision for float columns. |
Core tables reference
Content tables
page
page
The core of the wiki. Each page has exactly one row, identified by
page_namespace and page_title. The page_id is stable across edits and renames, but not across deletions and recreations.Key columns:page_id— Stable unique identifierpage_namespace— Integer namespace key (defined inincludes/Defines.php)page_title— Title with spaces replaced by underscores, max 255 bytespage_is_redirect— 1 if a redirect; a corresponding row exists in theredirecttablepage_latest— Foreign key torevision.rev_idof the current revisionpage_len— Uncompressed length in bytes of the current source textpage_touched— Invalidation timestamp for rendered cachespage_content_model— Content model identifier (e.g.wikitext,json)
page_id. Unique index on (page_namespace, page_title).revision
revision
Every edit creates a row in
revision. Stores metadata about the edit; content is stored in the external storage backend.Key columns:rev_id— Unique identifier (bigint, autoincrement)rev_page— Foreign key topage.page_idrev_actor— Foreign key toactor.actor_id(the editor)rev_comment_id— Foreign key tocomment.comment_id(edit summary)rev_timestamp— When the revision was createdrev_minor_edit— 1 if the editor checked “minor edit”rev_deleted— Bitmask of visibility restrictionsrev_parent_id— Foreign key to previousrev_id(forms the edit history tree)
rev_page_timestamp (history), rev_actor_timestamp (contributions), rev_page_actor_timestamp (credits).actor
actor
Associates user names or IP addresses with integer IDs used by
revision, archive, recentchanges, and other tables.Key columns:actor_id— Unique identifier (bigint)actor_user— Foreign key touser.user_id, orNULLfor anonymous editsactor_name— Username or IP address (max 255 bytes)
actor_user and actor_name.archive
archive
Stores deleted pages and their revisions. Admins can view and restore entries via Special:Undelete.Key columns mirror
revision: ar_namespace, ar_title, ar_rev_id, ar_actor, ar_timestamp, ar_deleted, ar_page_id.User tables
user
user
Basic account information for registered users. Some multi-wiki sites share a single central user table via
$wgSharedDB.Key columns:user_id— Primary keyuser_name— Unique username; spaces allowed, not converted to underscoresuser_real_name— Optional display name for credit listingsuser_password— Hashed passworduser_email— Non-public email addressuser_touched— Invalidation timestamp for the browser cache of logged-in usersuser_editcount— Approximate count; may be out of sync with actual revision countuser_registration— Timestamp of account registration (NULL for old accounts)user_is_temp— 1 for temporary (auto-created) users
watchlist
watchlist
Tracks which pages each user is watching.Key columns:
wl_id— Primary keywl_user— Foreign key touser.user_idwl_namespace,wl_title— The watched pagewl_notificationtimestamp— Timestamp of the earliest unseen revision, orNULLif current revision is seen
(wl_user, wl_namespace, wl_title) used by Special:Watchlist.Link tracking tables
categorylinks
categorylinks
Tracks category membership. One row per (page, category) pair.Key columns:
cl_from— Foreign key topage.page_idcl_target_id— Foreign key tolinktarget.lt_idcl_sortkey— Binary sortkey for ordering members within a categorycl_type—'page','subcat', or'file'(for paginating category members)cl_collation_id— Foreign key to collation
imagelinks
imagelinks
Tracks images used inline on pages. Does not distinguish live from broken links.Key columns:
il_from— Foreign key topage.page_idof the containing pageil_from_namespace— Namespace of the containing pageil_target_id— Foreign key tolinktarget.lt_id
(il_target_id, il_from) used by Special:Whatlinkshere and file description page usage listings.templatelinks
templatelinks
Tracks template transclusions. Updated whenever a page is parsed.
Activity tables
recentchanges
recentchanges
A summary table for Special:RecentChanges. Contains edits from the last few days (older entries are pruned by maintenance scripts).Key columns:
rc_id— Primary key (bigint)rc_timestamp— When the change occurredrc_actor— Foreign key toactor.actor_idrc_namespace,rc_title— The changed page (not updated on moves)rc_this_oldid—rev_idof the new revisionrc_last_oldid—rev_idof the previous revision (for diff links)rc_source— Source of the change entryrc_patrolled— 1 when an admin has reviewed the editrc_bot— 1 for edits by accounts with thebotrightrc_cur_id— Foreign key topage.page_id
change_tag
change_tag
Tracks tags for revisions, log entries, and recent changes.Key columns:
ct_tag_id— Foreign key tochange_tag_defct_rc_id— Foreign key torecentchanges.rc_id(nullable)ct_rev_id— Foreign key torevision.rev_id(nullable)ct_log_id— Foreign key tologging.log_id(nullable)
Schema migrations
Schema changes are applied by runningmaintenance/update.php. Each change is described by a migration patch file in sql/abstractSchemaChanges/.
A migration patch has before and after objects — each a full table definition. An empty before object ({}) signals table creation.
Write the patch file
Create a file in
sql/abstractSchemaChanges/ named patch-<description>.json. Define the before and after table states.Register it
Add the patch to the
$updates array in the relevant updater hook or directly in DatabaseUpdater.Defining tables in extensions
Extensions declare their database tables inextension.json using the $schema key inside a DatabaseSchema definition, pointing to an abstract schema JSON file.
sql/tables.json follows the same format as core’s sql/tables.json — an array of table definitions:
maintenance/update.php, MediaWiki creates any missing tables automatically.
