Core (Data Model) of WordPress Core

Preview:

DESCRIPTION

Basic developers understand, at some level, what WordPress "does" and how to modify its behavior. Better developers understand how to create objects, object meta data, and object relationships in WordPress (post types, meta, taxonomies). But the best engineers understand how all of this data actually manifests itself in the raw database architecture. Understanding how WordPress stores, organizes, and relates data when you strip away the PHP software layer can give you a deeper understanding and appreciation for the brilliance, deficits, potential, limits, and legacy of WordPress. We'll study WordPress's database schema, relate it back to core data model concepts like custom post types and taxonomies, meander holes in the models (like "why isn't there term meta??"), and even compare to past database structure to see how WordPress's database has evolved with the software.

Citation preview

The Core of WordPress CoreDigging Into WordPress’s Core Data Model

@jakemgold

• President of 10up - a growing WordPress-centric agency with 18 full time employees

• Clients like Juicy Couture, Time Inc, Condé Nast, Consumer Reports, TechCrunch, Universal Sports, Trulia, & More

• 10 of our 13 software engineers (including me!) contributed to WordPress 3.5, and we maintain some of the best rated, most downloaded plug-ins.

• Personal background: 15 years in web development, with a concentration in information systems & architecture

Premise

As a content management framework, WordPress mostly conceals abstract database complexity from us. Cool.

 $args  =  array(

     'post_type'  =>  'my_custom_post_type',

     'meta_key'  =>  'age',

     'orderby'  =>  'meta_value_num',

     'order'  =>  'ASC',

     'meta_query'  =>  array(

             array(                      'key'  =>  

'age',

                     'value'  =>  array(3,  4),

                     'compare'  =>  'IN',

             )      )  );  $query  =  new  WP_Que

ry($args);

 SELECT  *  FROM  

       ...  blah  blah  blah  ...

Premise

As a result, few consider how WordPress stores all the things when you peel the software layer back.

Less cool.

 $args  =  array(

     'post_type'  =>  'my_custom_post_type',

     'meta_key'  =>  'age',

     'orderby'  =>  'meta_value_num',

     'order'  =>  'ASC',

     'meta_query'  =>  array(

             array(                      'key'  =>  

'age',

                     'value'  =>  array(3,  4),

                     'compare'  =>  'IN',

             )      )  );  $query  =  new  WP_Que

ry($args);

 SELECT  *  FROM  

       ...  blah  blah  blah  ...

Premise

As a result, few consider how WordPress stores all the things when you peel the software layer back.

Less cool.

     'post_type'  =>  'my_custom_post_type',

     'orderby'  =>  'meta_value_num',

                     'value'  =>  array(3,  4),

 SELECT  *  FROM  

       ...  blah  blah  blah  ...

??

Premise

Studying how “the things” are stored (the data model) and its evolution empowers us to understand WordPress, its

potential, and its limitations in deeper ways.

     'post_type'  =>  'my_custom_post_type',

     'orderby'  =>  'meta_value_num',

                     'value'  =>  array(3,  4),

 SELECT  *  FROM  

       ...  blah  blah  blah  ...

??

Premise

Studying how “the things” are stored (the data model) and its evolution empowers us to understand WordPress, its

potential, and its limitations in deeper ways.

     'post_type'  =>  'my_custom_post_type',

     'orderby'  =>  'meta_value_num',

                     'value'  =>  array(3,  4),

 SELECT  *  FROM  

       ...  blah  blah  blah  ...

??

On Platforms & Abstraction

Good platforms make it easy to build stuff it wasn’t explicitly designed for.

On Platforms & Abstraction

Good platforms make it easy to build stuff it wasn’t explicitly designed for.

Good content platforms make it easy to create content it wasn’t explicitly designed for.

On Platforms & Abstraction

On Abstraction

If we wanted to build an application to manage project tasks, its data

model might look like this.

On Abstraction

If we wanted to build an application to manage project tasks, its data

model might look like this.

If we were building a platform that could be used for project tasks, or any other kind of content, it would

look very different.

On Abstraction

WordPress’s data model essentially handles abstraction with:One fairly generic content object table: wp_posts

Field TypeID bigint(20)  unsignedpost_author bigint(20)  unsignedpost_date datetimepost_date_gmt datetimepost_content longtextpost_title textpost_excerpt textpost_status varchar(20)comment_status varchar(20)ping_status varchar(20)post_password varchar(20)post_name varchar(200)to_ping textpinged textpost_modified datetimepost_modified_gmt datetimepost_content_filtered longtextpost_parent bigint(20)  unsignedguid varchar(255)menu_order int(11)post_type varchar(20)post_mime_type varchar(100)comment_count bigint(20)

WordPress’s data model essentially handles abstraction with:One fairly generic content object table: wp_posts

Field TypeID bigint(20)  unsignedpost_author bigint(20)  unsignedpost_date datetimepost_date_gmt datetimepost_content longtextpost_title textpost_excerpt textpost_status varchar(20)comment_status varchar(20)ping_status varchar(20)post_password varchar(20)post_name varchar(200)to_ping textpinged textpost_modified datetimepost_modified_gmt datetimepost_content_filtered longtextpost_parent bigint(20)  unsignedguid varchar(255)menu_order int(11)post_type varchar(20)post_mime_type varchar(100)comment_count bigint(20)

post_contentgeneric field for content

WordPress’s data model essentially handles abstraction with:One fairly generic content object table: wp_posts

Field TypeID bigint(20)  unsignedpost_author bigint(20)  unsignedpost_date datetimepost_date_gmt datetimepost_content longtextpost_title textpost_excerpt textpost_status varchar(20)comment_status varchar(20)ping_status varchar(20)post_password varchar(20)post_name varchar(200)to_ping textpinged textpost_modified datetimepost_modified_gmt datetimepost_content_filtered longtextpost_parent bigint(20)  unsignedguid varchar(255)menu_order int(11)post_type varchar(20)post_mime_type varchar(100)comment_count bigint(20)

post_statusgeneric field for identifier of

state of content object

WordPress’s data model essentially handles abstraction with:One fairly generic content object table: wp_posts

Field TypeID bigint(20)  unsignedpost_author bigint(20)  unsignedpost_date datetimepost_date_gmt datetimepost_content longtextpost_title textpost_excerpt textpost_status varchar(20)comment_status varchar(20)ping_status varchar(20)post_password varchar(20)post_name varchar(200)to_ping textpinged textpost_modified datetimepost_modified_gmt datetimepost_content_filtered longtextpost_parent bigint(20)  unsignedguid varchar(255)menu_order int(11)post_type varchar(20)post_mime_type varchar(100)comment_count bigint(20)

post_parentobject hierarchy

WordPress’s data model essentially handles abstraction with:One fairly generic content object table: wp_posts

Field TypeID bigint(20)  unsignedpost_author bigint(20)  unsignedpost_date datetimepost_date_gmt datetimepost_content longtextpost_title textpost_excerpt textpost_status varchar(20)comment_status varchar(20)ping_status varchar(20)post_password varchar(20)post_name varchar(200)to_ping textpinged textpost_modified datetimepost_modified_gmt datetimepost_content_filtered longtextpost_parent bigint(20)  unsignedguid varchar(255)menu_order int(11)post_type varchar(20)post_mime_type varchar(100)comment_count bigint(20)

menu_orderrelative order of content

WordPress’s data model essentially handles abstraction with:One fairly generic content object table: wp_posts

Field TypeID bigint(20)  unsignedpost_author bigint(20)  unsignedpost_date datetimepost_date_gmt datetimepost_content longtextpost_title textpost_excerpt textpost_status varchar(20)comment_status varchar(20)ping_status varchar(20)post_password varchar(20)post_name varchar(200)to_ping textpinged textpost_modified datetimepost_modified_gmt datetimepost_content_filtered longtextpost_parent bigint(20)  unsignedguid varchar(255)menu_order int(11)post_type varchar(20)post_mime_type varchar(100)comment_count bigint(20)

post_type (!!!)generic identifier for type of

content object

WordPress’s data model essentially handles abstraction with:One fairly generic content object table: wp_posts

Field TypeID bigint(20)  unsignedpost_author bigint(20)  unsignedpost_date datetimepost_date_gmt datetimepost_content longtextpost_title textpost_excerpt textpost_status varchar(20)comment_status varchar(20)ping_status varchar(20)post_password varchar(20)post_name varchar(200)to_ping textpinged textpost_modified datetimepost_modified_gmt datetimepost_content_filtered longtextpost_parent bigint(20)  unsignedguid varchar(255)menu_order int(11)post_type varchar(20)post_mime_type varchar(100)comment_count bigint(20)

post_mime_typestandards based identifier of

the type of information contained in content

WordPress’s data model essentially handles abstraction with:A completely abstract content object properties table: wp_postmeta

Field Type

meta_id bigint(20)

post_id bigint(20)

meta_key varchar(255)

meta_value text

Meta data is defined as “data about data.”It doesn’t get more abstract.

WordPress’s data model essentially handles abstraction with:A completely abstract content object properties table: wp_postmeta

Field Type

meta_id bigint(20)

post_id bigint(20)

meta_key varchar(255)

meta_value text

Meta data is defined as “data about data.”It doesn’t get more abstract.

identifier of content objectthis is all about

WordPress’s data model essentially handles abstraction with:A completely abstract content object properties table: wp_postmeta

Field Type

meta_id bigint(20)

post_id bigint(20)

meta_key varchar(255)

meta_value text

Meta data is defined as “data about data.”It doesn’t get more abstract.

arbitrary identifier for the content property we want

to define

WordPress’s data model essentially handles abstraction with:A completely abstract content object properties table: wp_postmeta

Field Type

meta_id bigint(20)

post_id bigint(20)

meta_key varchar(255)

meta_value text

Meta data is defined as “data about data.”It doesn’t get more abstract.

arbitrary value for ourarbitrary property

WordPress’s data model essentially handles abstraction with:An abstract set of tables for content classification.

WordPress’s data model essentially handles abstraction with:An abstract set of tables for content classification.

Field Type

term_id bigint(20)  unsigned

name varchar(200)

slug varchar(200)

term_group bigint(10)

wp_termsArbitrary classifications for content objects.

WordPress’s data model essentially handles abstraction with:An abstract set of tables for content classification.

Field Type

term_id bigint(20)  unsigned

name varchar(200)

slug varchar(200)

term_group bigint(10)

wp_termsArbitrary classifications for content objects.

Field Type

term_taxonomy_id bigint(20)  unsigned

term_id bigint(20)  unsigned

taxonomy varchar(32)

description longtext

parent bigint(20)  unsigned

count bigint(20)

wp_term_taxonomyDescribes the arbitrary classification (term) for each unique classification group (taxonomy).

WordPress’s data model essentially handles abstraction with:An abstract set of tables for content classification.

Field Type

term_id bigint(20)  unsigned

name varchar(200)

slug varchar(200)

term_group bigint(10)

wp_termsArbitrary classifications for content objects.

Field Type

term_taxonomy_id bigint(20)  unsigned

term_id bigint(20)  unsigned

taxonomy varchar(32)

description longtext

parent bigint(20)  unsigned

count bigint(20)

wp_term_taxonomyDescribes the arbitrary classification (term) for each unique classification group (taxonomy).

Field Type

object_id bigint(20)  unsigned

term_taxonomy_id bigint(20)  unsigned

term_order int(11)

wp_term_relationshipsAssociates classifications with content objects.

WordPress’s data model essentially handles abstraction with:An abstract set of tables for content classification.

Field Type

term_id bigint(20)  unsigned

name varchar(200)

slug varchar(200)

term_group bigint(10)

wp_termsArbitrary classifications for content objects.

Field Type

term_taxonomy_id bigint(20)  unsigned

term_id bigint(20)  unsigned

taxonomy varchar(32)

description longtext

parent bigint(20)  unsigned

count bigint(20)

wp_term_taxonomyDescribes the arbitrary classification (term) for each unique classification group (taxonomy).

Huh?... oops.

WordPress’s data model essentially handles abstraction with:An abstract set of tables for content classification.

Field Type

object_id bigint(20)  unsigned

term_taxonomy_id bigint(20)  unsigned

term_order int(11)

wp_term_relationshipsAssociates classifications with content objects.

Anything else here surprise you?

WordPress’s data model essentially handles abstraction with:An abstract set of tables for content classification.

Field Type

object_id bigint(20)  unsigned

term_taxonomy_id bigint(20)  unsigned

term_order int(11)

wp_term_relationshipsAssociates classifications with content objects.

Anything else here surprise you?

term_order (??)WordPress’s API does not support ordering terms. Its data model actually does.

WordPress’s data model essentially handles abstraction with:An abstract set of tables for content classification.

Field Type

object_id bigint(20)  unsigned

term_taxonomy_id bigint(20)  unsigned

term_order int(11)

wp_term_relationshipsAssociates classifications with content objects.

Anything else here surprise you?

term_order (??)WordPress’s API does not support ordering terms. Its data model actually does.

Where’s term meta?The data model doesn’t yet

(really) support arbitrary data about a classification / term.

WordPress’s data model essentially handles abstraction with:A completely abstract global data table: wp_options

Field Type

option_id bigint(20)  unsigned

option_name varchar(64)

option_value longtext

autoload varchar(20)

WordPress’s data model essentially handles abstraction with:A completely abstract global data table: wp_options

Field Type

option_id bigint(20)  unsigned

option_name varchar(64)

option_value longtext

autoload varchar(20)

arbitrary name of data

WordPress’s data model essentially handles abstraction with:A completely abstract global data table: wp_options

Field Type

option_id bigint(20)  unsigned

option_name varchar(64)

option_value longtext

autoload varchar(20)

arbitrary value for said data

Other tables and abstraction!

wp_comments & wp_commentmetaComments are a specific type of content object, separated

for legacy and scalability reasons.

wp_users & wp_usermetaUsers a special object (not really content). Also have arbitrary properties / meta data.

wp_linksA specific content object (and leftover.)

How did we get here?

Why do we call content objects “posts”?

And why the heck is there a “links” table?

WordPress 1.5: Blogging Software

WordPress 1.5: Blogging Software

Tables:wp_categorieswp_comments

wp_linkcategorieswp_links

wp_optionswp_post2catwp_postmeta

wp_postswp_users

WordPress 1.5*: Blogging Software

Tables:wp_categorieswp_comments

wp_linkcategorieswp_links

wp_optionswp_post2catwp_postmeta

wp_postswp_users

Field TypeID bigint(20)  unsignedpost_author int(4)post_date datetimepost_date_gmt datetimepost_content longtextpost_title textpost_category int(4)post_excerpt textpost_status enum('publish','draft','private','static','object')comment_status enum('open','closed','registered_only')ping_status enum('open','closed')post_password varchar(20)post_name varchar(200)to_ping textpinged textpost_modified datetimepost_modified_gmt datetimepost_content_filtered textpost_parent int(11)guid varchar(255)menu_order int(11)

WordPress 1.5: Blogging Software

Tables:wp_categorieswp_comments

wp_linkcategorieswp_links

wp_optionswp_post2catwp_postmeta

wp_postswp_users

Field Type

meta_id bigint(20)

post_id bigint(20)

meta_key varchar(255)

meta_value text

WordPress 1.5: Blogging Software

Tables:wp_categorieswp_comments

wp_linkcategorieswp_links

wp_optionswp_post2catwp_postmeta

wp_postswp_users

Field Type

meta_id bigint(20)

post_id bigint(20)

meta_key varchar(255)

meta_value text

Arbitrary content (post) meta data!Early sign of data model

abstraction... and possibility!

WordPress 2.0: Foundation for Content Abstraction

Tables:wp_categorieswp_comments

wp_linkcategorieswp_links

wp_optionswp_post2catwp_postmeta

wp_postswp_usermeta

wp_users

Field TypeID bigint(20)  unsignedpost_author bigint(20)post_date datetimepost_date_gmt datetimepost_content longtextpost_title textpost_category int(4)post_excerpt textpost_status enum('publish','draft','private','static','object',  'attachment')

comment_status enum('open','closed','registered_only')ping_status enum('open','closed')post_password varchar(20)post_name varchar(200)to_ping textpinged textpost_modified datetimepost_modified_gmt datetimepost_content_filtered textpost_parent bigint(20)guid varchar(255)menu_order int(11)post_type varchar(100)post_mime_type varchar(100)comment_count bigint(20)

WordPress 2.0: Foundation for Content Abstraction

Tables:wp_categorieswp_comments

wp_linkcategorieswp_links

wp_optionswp_post2catwp_postmeta

wp_postswp_usermeta

wp_users

Field TypeID bigint(20)  unsignedpost_author bigint(20)post_date datetimepost_date_gmt datetimepost_content longtextpost_title textpost_category int(4)post_excerpt textpost_status enum('publish','draft','private','static','object',  'attachment')

comment_status enum('open','closed','registered_only')ping_status enum('open','closed')post_password varchar(20)post_name varchar(200)to_ping textpinged textpost_modified datetimepost_modified_gmt datetimepost_content_filtered textpost_parent bigint(20)guid varchar(255)menu_order int(11)post_type varchar(100)post_mime_type varchar(100)comment_count bigint(20)

Origin: Pages & Media.Post type API wouldn’t

come till 3.0!

WordPress 2.0: Foundation for Content Types

Tables:wp_categorieswp_comments

wp_linkcategorieswp_links

wp_optionswp_post2catwp_postmeta

wp_postswp_usermeta

wp_users

WordPress 2.0: Foundation for Content Types

Tables:wp_categorieswp_comments

wp_linkcategorieswp_links

wp_optionswp_post2catwp_postmeta

wp_postswp_usermeta

wp_users

Field Type

umeta_id bigint(20)

user_id bigint(20)

meta_key varchar(255)

meta_value longtext

User objects are now extensible with arbitrary meta data.

More signs of extensibility!

WordPress 2.3: Classifications Get Abstract

WordPress 2.3: Classifications Get Abstract

Tables:wp_comments

wp_linkswp_options

wp_postmetawp_postswp_terms

wp_term_relationshipswp_term_taxonomy

wp_usermetawp_users

Removed Tables:wp_categories

wp_linkcategorieswp_post2cat

WordPress 2.3: Classifications Get Abstract

Tables:wp_comments

wp_linkswp_options

wp_postmetawp_postswp_terms

wp_term_relationshipswp_term_taxonomy

wp_usermetawp_users

Removed Tables:wp_categories

wp_linkcategorieswp_post2cat

Impetus: Tags.Taxonomy registration API

wouldn’t come till 2.9!

Category fields in post and links tables don’t get removed

until 2.8.

WordPress 2.5: Enum Values Fade Away

post_status,  comment_status,  ping_statusin wp_posts table change from enumerated list (enforced options

in data model) to freeform field

term_order  curiously gets added to wp_term_relationships table

WordPress 2.9: Comment Objects Get Meta

WordPress 2.9: Comment Objects Get Meta

Tables:wp_comments

wp_commentmetawp_links

wp_optionswp_postmeta

wp_postswp_terms

wp_term_relationshipswp_term_taxonomy

wp_usermetawp_users

WordPress 3.0: Groups of Objects

more detail: http://codex.wordpress.org/Database_Description/2.0

WordPress Network Mode (Multisite)

(which we’re not going to study for time’s sake)

The Future of WordPress’s Data Model

The Future of WordPress’s Data Model

The Future of WordPress’s Data Model

• Clean up of taxonomy tables, and addition of term meta data?

• Legacy specific content object tables (links) fall away? (note 3.5)

• Post table fields very specific to blog posts get moved over to post meta or taxonomies?

• Improvements to relationships between content objects?

The Core of WordPress CoreThanks! Slides will be available at 10up.com.

Feedback? Want more? @jakemgold on Twitter

Recommended