In the earlier article “Understanding WordPress content types,” I introduced the four main content types in WordPress. This time, we are going to look at the additional data related to those content types: metadata. In the WordPress database, there are four primary data types, and they are stored in these four tables:
- posts
- users
- comments
- links
The first three of those data types all have their own metadata, and each one has its own table for storing that metadata.
What is metadata?
Metadata can be understood as data about data. Wikipedia describes two kinds of metadata:
Structured metadata is data about the design and structure of data. Calling it “data about data” is probably the most fitting description. Descriptive metadata is another part of the data itself, effectively the additional data attached to the main data.
In practice, the easiest way to understand metadata is as additional attached data. From a database design perspective, we could store every piece of post data in a single table. Then once we knew the post ID, we could retrieve one row from that table and get everything related to the post very quickly.
But that design has a major weakness: it is not flexible or extensible. Imagine that all post data were stored in a single table, and now we wanted to add another field, such as the location where a post was published. How would we do that? Would we ask users to modify the database table itself? That is obviously not realistic.
Metadata exists to solve exactly that problem. Metadata acts like an auxiliary table linked to the main record through an ID field. In addition to the post ID, the metadata table contains two fields: meta_key and meta_value. The key defines the name of the data, and the value stores the data itself. In the example above, if we wanted to add a location field to a post, we would just add one row with the post ID, a meta_key of address, and a meta_value of “Beijing.” If we need more fields, we add more rows. It is very flexible.
Metadata tables
WordPress has three metadata tables:
wp_postmetastores post metadata, including attachments, navigation menu items, and revision data.wp_commentmetastores comment metadata.wp_usermetastores user metadata.
Among all WordPress objects, only links do not have metadata. In fact, that table has already been deprecated and will eventually be removed in a future version.
All metadata tables use almost the same structure:
- ID: the post, comment, or user ID associated with the record.
- Meta ID: the ID of the metadata record itself.
- Key: the metadata key.
- Value: the value stored in that metadata record.
WordPress can store a very large amount of metadata with this simple structure. It also means the functions used to query post metadata, comment metadata, and user metadata are all very similar.
Metadata stored in WordPress
The metadata stored in each WordPress site may be different, because themes and plugins can create their own metadata as needed. Here are some of the most common uses of metadata in WordPress.
- Custom fields. Additional post data is stored in the
wp_postmetatable. We can add that data through WordPress’s default custom fields UI or by creating custom metaboxes. On many multi-user sites, using metaboxes is usually a better experience for users. - User metadata. The
wp_usermetatable contains a lot of user-related information, such as roles, capabilities, dashboard settings, and more. - Metadata added by themes or plugins. Plugins that work with comments, such as Akismet, add comment metadata to the
wp_commentmetatable. Other plugins may add metadata to the post metadata table. SEO plugins are a common example. Even if metadata can technically be added in a theme, it is still better to add it through plugins when the data belongs to functionality rather than presentation.
The fields in the main tables for posts, comments, and users are fixed. Any additional data related to those content types that does not fit into the main tables gets stored in the corresponding metadata tables.
If you need to add an extra field for one of these content types, you should always add it through its metadata table rather than by extending the schema of the primary content table.
Querying and outputting metadata
WordPress uses the Metadata API to add, update, retrieve, and delete metadata. The API includes a set of generic metadata functions, as well as more specific helper functions for each content type. For example, get_post_meta() is just a specialized form of the generic get_metadata() function.
In practice, you should use the more specific helper functions whenever possible. They are easier to read, more convenient, and less error-prone. These are the main ones:
| Add Metadata | Get Metadata | Update Metadata | Delete Metadata | |
|---|---|---|---|---|
| Posts | add_post_meta() |
get_post_meta() |
update_post_meta() |
delete_post_meta() |
| Users | add_user_meta() |
get_user_meta() |
update_user_meta() |
delete_user_meta() |
| Comments | add_comment_meta() |
get_comment_meta() |
update_comment_meta() |
delete_comment_meta() |
| Arguments | $post_id,$meta_key,$meta_value,$unique (optional) |
$post_id,$meta_key,$single (optional) |
$post_id,$meta_key,$meta_value,$prev_value (optional) |
$post_id,$meta_key,$meta_value (optional) |
You can use the functions above directly in themes and plugins. For example, on a single post page in a theme, you can output metadata related to the current post like this:
$metavalue = get_post_meta( get_the_ID(), 'my_meta_key' true);
// 检查自定义字段是否有值
if ( ! empty( $metavalue ) ) {
echo $metavalue;
}
That is just the simplest possible way to output metadata. With a bit more study, you will find a lot of other possibilities. I will cover more of those in a separate article.
Summary
WordPress uses three metadata tables to store metadata for three different types of content. These tables store the additional data that does not belong in the primary tables wp_posts, wp_users, and wp_comments. If your theme or plugin needs to add data related to those content types, metadata is the right place to store it, and the way you query, update, and delete that data is broadly consistent across all three cases.
