VOOZH about

URL: https://deepwiki.com/auth0/wordpress/3.6-database-schema

⇱ Database Schema | auth0/wordpress | DeepWiki


Loading...
Menu

Database Schema

This document describes the custom database tables used by the Auth0 WordPress plugin for account mapping and event synchronization. The plugin uses custom MySQL tables rather than WordPress's standard options/meta tables to achieve high performance with large user bases.

For information about how these tables are used during authentication flows, see Authentication Flow. For details on the synchronization system that processes the queue table, see User Synchronization.

Overview

The plugin creates two custom database tables with the wp_auth0_ prefix (where wp_ is the configurable WordPress table prefix):

Table NamePurposePrimary Use Case
wp_auth0_accountsMaps WordPress users to Auth0 connection identifiersIdentity resolution during login
wp_auth0_syncQueues user lifecycle events for background processingAsynchronous synchronization to Auth0

Both tables support WordPress multisite installations through site and blog columns that namespace data by network and blog ID.

Sources: src/Database.php14-29

Table: auth0_accounts

Schema Definition


Sources: src/Database.php101-119

Column Specifications

ColumnTypeConstraintsDescription
idBIGINTPRIMARY KEY, AUTO_INCREMENTUnique row identifier
siteTINYINTNOT NULLWordPress network ID (0 for single-site)
blogBIGINTNOT NULLWordPress blog/site ID
userBIGINTNOT NULLWordPress user ID (foreign key to wp_users.ID)
auth0TEXTNOT NULLAuth0 connection identifier (sub claim from JWT)

The table is created using WordPress's maybe_create_table() function, which only creates the table if it doesn't already exist, making it safe to call on every request.

Sources: src/Database.php101-119

Purpose and Usage

The auth0_accounts table maintains the many-to-one relationship between Auth0 connection identifiers and WordPress users. A single WordPress user can have multiple Auth0 connections (e.g., logging in via Google, GitHub, or username/password), each represented by a unique row.

Write Operations

Account connections are created during successful authentication in Authentication::createAccountConnection():


The method generates a cache key using hash('sha256', $connection . '::' . $network . '!' . $blog) to avoid redundant database queries within a 120-second window.

Sources: src/Actions/Authentication.php53-88

Read Operations

During login, Authentication::getAccountByConnection() looks up WordPress users by their Auth0 sub:


Sources: src/Actions/Authentication.php111-154

Delete Operations

When WordPress users are deleted, Authentication::deleteAccountConnections() removes all associated Auth0 connections:

Sources: src/Actions/Authentication.php90-109

Multisite Considerations

The site and blog columns enable proper isolation in WordPress multisite networks. Queries always filter by both:


This ensures users on different sites within a network can have independent Auth0 connections, even with the same email address.

Sources: src/Actions/Authentication.php113-132

Table: auth0_sync

Schema Definition


Sources: src/Database.php121-141

Column Specifications

ColumnTypeConstraintsDescription
idBIGINTPRIMARY KEY, AUTO_INCREMENTUnique row identifier
siteTINYINTNOT NULLWordPress network ID
blogBIGINTNOT NULLWordPress blog/site ID
createdINT(11)NOT NULLUnix timestamp when event was queued
payloadTEXTNOT NULLJSON-encoded event data
hashsumVARCHAR(64)NOT NULL, UNIQUESHA-256 hash of payload for deduplication
lockedINT(1)NOT NULLConcurrent processing lock (0=unlocked, 1=locked)

The hashsum column has a UNIQUE constraint, preventing duplicate events from being queued.

Sources: src/Database.php121-141

Purpose and Usage

The auth0_sync table implements a durable event queue for asynchronous synchronization between WordPress and Auth0. When WordPress user events occur (creation, update, deletion), they are immediately queued here for later processing by WordPress cron jobs.

Event Types

The payload column contains JSON objects with an event field indicating the type:

Event TypeTriggered ByPayload Structure
wp_user_createdUser created via WordPress UI{"event": "wp_user_created", "user": <id>}
wp_user_updatedUser profile updated{"event": "wp_user_updated", "user": <id>}
wp_user_deletedUser deleted{"event": "wp_user_deleted", "user": <id>, "connection": "<sub>"}

Sources: src/Actions/Authentication.php283-308 src/Actions/Authentication.php323-348 src/Actions/Authentication.php604-628

Write Operations

Events are queued synchronously when WordPress hooks fire:


The duplicate check ensures that rapidly repeated events (e.g., multiple profile updates) don't flood the queue.

Sources: src/Actions/Authentication.php270-308 src/Actions/Authentication.php591-629

Read and Process Operations

The WordPress cron job AUTH0_CRON_SYNC processes queued events via Sync::onBackgroundSync():


The processing is batched (10 events per cron run) and deletions occur regardless of API success to prevent infinite retry loops.

Sources: src/Actions/Sync.php214-254

Deduplication Strategy

The hashsum column serves as a deduplication key. Before inserting, the code checks:


If a row with the same hash exists, the insertion is skipped. This prevents duplicate events from being queued when WordPress hooks fire multiple times (a common occurrence during bulk operations or plugin conflicts).

Sources: src/Actions/Authentication.php287-290 src/Actions/Authentication.php328-331 src/Actions/Authentication.php608-611

Database Abstraction Layer

Database Class

The Database class provides a thin abstraction over WordPress's $wpdb global:


Sources: src/Database.php1-149

Key Methods

MethodPurposeUsage Pattern
createTable($table)Creates table if not existsCalled before first access via prepDatabase()
getTableName($table)Returns prefixed table namewp_auth0_{table}
insertRow($table, $data, $formats)Insert with prepared statementQueuing events, creating connections
selectRow($select, $from, $query, $args)Single row queryLooking up connections
selectResults($select, $from, $query, $args)Multi-row queryFetching queue items
deleteRow($table, $where, $format)Delete with prepared statementRemoving processed events

All query methods use $wpdb->prepare() for SQL injection protection.

Sources: src/Database.php31-99

Table Creation Pattern

Tables are created lazily using WordPress's maybe_create_table() function, which compares the desired schema against the existing table structure and only executes DDL if necessary:


This is idempotent and safe to call repeatedly. The plugin calls createTable() before accessing tables through the prepDatabase() helper, which adds an additional caching layer using transients (30-minute TTL) to avoid redundant checks.

Sources: src/Database.php101-141 src/Actions/Authentication.php645-658

Database Access Patterns

Connection Mapping Flow


Sources: src/Actions/Authentication.php660-724 src/Actions/Authentication.php111-154

Synchronization Queue Flow


Sources: src/Actions/Authentication.php270-351 src/Actions/Sync.php214-254

Performance Considerations

Why Custom Tables?

The plugin uses custom database tables instead of WordPress's options/meta tables for three primary reasons:

  1. Query Performance: Direct table access with indexes is significantly faster than WordPress's serialized option storage or meta queries with JOIN operations
  2. Scalability: Large user bases generate thousands of account mappings and sync events; custom tables handle this volume efficiently
  3. Transaction Integrity: Queue operations require atomic inserts with duplicate checks, which are better supported by dedicated tables with UNIQUE constraints

The documentation explicitly notes this decision in comments about performance optimization.

Sources: src/Database.php1-10

Caching Strategy

The plugin implements multi-tier caching for auth0_accounts lookups:


TTL: 120 seconds for both transients and object cache Cache Key Format: auth0_account_ + SHA-256 hash of {sub}::{network}!{blog}

This strategy minimizes database queries during high-traffic periods when the same users repeatedly authenticate.

Sources: src/Actions/Authentication.php111-154

Database Preparation Optimization

Before accessing custom tables, the code checks if table creation is needed using a cached flag:


This ensures createTable() (which calls maybe_create_table()) runs at most once per 30 minutes per table, avoiding repeated filesystem and database metadata checks.

Sources: src/Actions/Authentication.php645-658

Multisite Architecture

Both tables include site and blog columns to support WordPress multisite (network) installations:

ColumnWordPress FunctionScope
siteget_current_network_id()Network-level isolation
blogget_current_blog_id()Site-level isolation within network

All queries filter by both columns, ensuring complete data isolation between sites. This allows different sites in a network to:

  • Use different Auth0 tenants
  • Map the same Auth0 connection to different WordPress users
  • Maintain independent synchronization queues

For single-site WordPress installations, site is 0 and blog is 1.

Sources: src/Actions/Authentication.php55-56 src/Actions/Authentication.php113-114 src/Actions/Authentication.php276-277


Sources: