WooCommerce is a WordPress plugin, and to take advantage of WordPress’s flexibility the WooCommerce team originally stored orders as custom post types. Anyone who has developed a WooCommerce theme or plugin is probably already familiar with that design choice.
The problems with storing WooCommerce data as posts
Messy data access patterns in WooCommerce
Because products and orders are stored as post types, we can use WordPress functions such as get_posts() or WP_Query to retrieve them. But the fields in wp_posts are limited, so a lot of extra product and order data ends up in post_meta. That means developers also need get_post_meta() and update_post_meta() to work with the data.
At the same time, WooCommerce provides helper functions such as wc_get_product* and wc_get_order* to access the same kinds of data.
Some developers prefer using raw MySQL queries or an ORM to read and write WooCommerce product and order data directly from the database.
It is, frankly, a mess.
The performance cost of huge amounts of post_meta
There is also a performance problem. By default, when a customer places an order, WooCommerce creates at least 40 post_meta rows for that order. If a site receives 10 orders per day, the post_meta table grows by 400 rows per day. The bigger that table becomes, the slower order-related queries can become. That is not something we can ignore.
To solve the confusion around data access, developers need a single, consistent way to access data. To solve the performance problem, WooCommerce also needs the option to change where and how data is stored.
What is the WooCommerce CRUD abstract class?
WooCommerce 3.0 introduced new CRUD classes to address exactly those issues. This is an abstraction layer that makes it possible to do a few important things:
- Define a custom data structure for each kind of WooCommerce data.
- Validate data consistently when it is stored or retrieved.
- Let developers work with API methods instead of worrying about the storage location.
- Move data into custom database tables without forcing developers to change how they call it.
- Use the same code to update data in the admin, in the REST API, and in the CLI so the whole system stays unified.
- Write less code, which also means fewer bugs and better unit-test coverage.
Which data types are intended to move into this CRUD system?
- Products
- Customers
- Orders
- Order items
- Coupons
These are the main data types in WooCommerce. At the time of writing, each of them is still effectively stored through custom post types, except for customer data, which lives in users and user meta.
A comparison of the two WooCommerce data-storage approaches
Let us look at the new CRUD system through a simple example. Suppose we need to update the billing first and last name on an order. With the old approach, the code might look like this:
$order_id = 100;
update_post_meta( $order_id, '_billing_first_name', 'Fred' );
update_post_meta( $order_id, '_billing_last_name', 'Flintstone' );
In that approach, we need to know the order post ID, the exact meta keys, and we still have to handle our own validation. It is tedious.
With CRUD, the same update becomes:
$order_id = 100;
$order = wc_get_order( $order ); //得到 $order 类
$order->set_billing_first_name( 'Fred );
$order->set_billing_last_name( 'Flintstone' );
$order->save();
At first glance the second example looks like it has one extra line, but the important difference is that we only need to know one piece of data: $order_id. The rest can be discovered through the class API, and modern IDEs such as PHPStorm can help a lot. More importantly, we no longer need to care how WooCommerce stores the data internally, which makes future versions easier to support.
Why the new WooCommerce CRUD classes matter
On the surface, it may look like WooCommerce is gradually moving away from WordPress. In reality, WooCommerce still uses a lot of WordPress APIs under the hood, so fully separating from WordPress is unlikely.
Overall, this is a positive change. The WooCommerce CRUD layer gives developers a more unified interface for data access, which means better stability. As long as we use the standard APIs, we do not need to worry so much about changes in the underlying data storage. And because the data-access layer is abstracted, WooCommerce data can eventually be stored in different tables without forcing developers to rewrite how they interact with it.
