Learn how WordPress stores website information in a database, understand important database tables, and explore how PHP and SQL work together to retrieve and manage WordPress data.
A database is an organized collection of information that can be stored, retrieved, updated, and managed electronically. WordPress commonly uses MySQL or a compatible database system such as MariaDB.
A WordPress database stores information such as:
WordPress uses PHP to process requests and communicate with the database. When a visitor opens a blog post, WordPress retrieves the relevant information and generates the page.
A standard WordPress installation creates several core tables.
The table names usually begin with the database prefix
wp_, but the prefix can be different.
| Table | Purpose |
|---|---|
wp_posts |
Stores posts, pages, attachments, and other post types. |
wp_postmeta |
Stores additional metadata associated with posts. |
wp_users |
Stores WordPress user account information. |
wp_usermeta |
Stores additional information about users. |
wp_comments |
Stores comments associated with posts and pages. |
wp_commentmeta |
Stores additional comment metadata. |
wp_terms |
Stores taxonomy terms, such as category and tag names. |
wp_term_taxonomy |
Stores taxonomy information for terms. |
wp_term_relationships |
Connects posts or other objects with taxonomy terms. |
wp_options |
Stores many site settings and plugin options. |
wp_links |
Legacy table for links; often unused on modern sites. |
wp_ prefix. Always check the actual prefix in the
site's configuration and use WordPress APIs where possible.
The wp_posts table is one of the most important
WordPress database tables. It stores several types of content,
including blog posts, pages, and media attachment records.
| Column | Meaning |
|---|---|
ID |
Unique identifier for the content record. |
post_author |
ID of the author. |
post_date |
Publication date or record date. |
post_content |
Main content. |
post_title |
Title of the content. |
post_status |
Status, such as publish or draft. |
post_name |
URL-friendly slug. |
post_type |
Content type, such as post, page, or attachment. |
SQL stands for Structured Query Language. It is used to communicate with relational databases, including MySQL and MariaDB.
Common SQL operations include:
| Command | Purpose |
|---|---|
SELECT |
Retrieve data. |
INSERT |
Add a new record. |
UPDATE |
Modify existing records. |
DELETE |
Remove records. |
WHERE |
Filter records according to a condition. |
ORDER BY |
Sort query results. |
You can use a SQL query to retrieve published blog post titles. The following example is for learning and read-only inspection.
SELECT ID, post_title, post_date
FROM wp_posts
WHERE post_type = 'post'
AND post_status = 'publish'
ORDER BY post_date DESC
LIMIT 10;
Explanation:
SELECT chooses the columns to retrieve.FROM wp_posts specifies the table.WHERE filters for published blog posts.ORDER BY sorts the newest posts first.LIMIT 10 restricts the result to ten records.wp_posts with the actual table name
if your installation uses a different prefix.
phpMyAdmin is a web-based database management tool commonly included with local development packages and hosting panels.
On a live website, access phpMyAdmin through your hosting provider or another authorized database administration tool.
WordPress provides database functions and objects that developers
can use instead of creating a separate database connection.
The global $wpdb object is the standard WordPress
database interface.
<?php
global $wpdb;
$posts = $wpdb->get_results(
$wpdb->prepare(
"SELECT ID, post_title
FROM {$wpdb->posts}
WHERE post_type = %s
AND post_status = %s
ORDER BY post_date DESC
LIMIT %d",
'post',
'publish',
10
)
);
if ($posts) {
foreach ($posts as $post) {
echo '<h3>' .
esc_html($post->post_title) .
'</h3>';
}
} else {
echo '<p>No published posts found.</p>';
}
?>
Explanation:
$wpdb is the WordPress database object.$wpdb->posts provides the correctly prefixed posts table name.prepare() safely prepares the query using placeholders.get_results() retrieves multiple records.foreach loops through the returned posts.esc_html() safely escapes titles before displaying them as HTML text.
The get_var() method retrieves a single value from
a database query.
<?php
global $wpdb;
$count = $wpdb->get_var(
$wpdb->prepare(
"SELECT COUNT(*)
FROM {$wpdb->posts}
WHERE post_type = %s
AND post_status = %s",
'post',
'publish'
)
);
echo 'Published Posts: ' . absint($count);
?>
The query counts records that are published blog posts.
absint() converts the displayed count to a
non-negative integer.
WordPress provides $wpdb->insert() to insert a
record into a database table. The following example inserts a
row into a custom table named wp_demo_messages.
<?php
global $wpdb;
$table_name = $wpdb->prefix . 'demo_messages';
$data = array(
'message' => 'Hello WordPress'
);
$formats = array('%s');
$result = $wpdb->insert(
$table_name,
$data,
$formats
);
if ($result !== false) {
echo 'Record inserted successfully.';
} else {
echo 'Unable to insert record.';
}
?>
wp_demo_messages with a compatible
message column. It will not work until that table
exists. For real applications, create custom tables using a
properly designed installation or upgrade routine. Do not create
arbitrary tables or modify production data without a backup.
WordPress provides $wpdb->update() and
$wpdb->delete() for modifying and removing records.
Always use an appropriate condition to target the intended rows.
<?php
global $wpdb;
$table_name = $wpdb->prefix . 'demo_messages';
$updated = $wpdb->update(
$table_name,
array(
'message' => 'Updated message'
),
array(
'id' => 1
),
array('%s'),
array('%d')
);
?>
<?php
global $wpdb;
$table_name = $wpdb->prefix . 'demo_messages';
$deleted = $wpdb->delete(
$table_name,
array(
'id' => 1
),
array('%d')
);
?>
In both examples, the condition targets the record whose ID is 1. Change the condition to match the intended record. These operations change database data, so test them using sample data before using them on a live website.
$wpdb->prepare() for SQL queries containing variable values.| Error | Possible Solution |
|---|---|
| Table does not exist | Check the database name, table name, and prefix. |
| Unknown column | Verify the column name and table structure. |
| Database connection error | Check the database service and WordPress database configuration. |
| Query returns no rows | Check the query conditions and available records. |
| SQL syntax error | Review SQL keywords, commas, parentheses, and quotation marks. |
$wpdb->get_results() to retrieve post titles.$wpdb->get_var() to count published posts.wp_posts table stores posts, pages, and other post types.wp_.$wpdb object provides WordPress database functionality.get_results(), get_var(), and insert() support database operations.Choose the correct answer for each question.