Neither option are the correct option for your use case
Your question is barking up the wrong tree, because you neglected to mention that you intend to search for these posts based on the values the meta holds.
If you’re displaying a post, you can use either method, though the first is cleaner/simpler to handle in code. get_post_meta
is fast and relies on table indexes, and WP fetches the post meta in advance anyway.
The problem here is if you have thousands of post meta, or a handful of hyper big post meta, in the extreme cases this can cause you to run out of memory or prevent it being cached by object caches
But What If You Searched For Them?
Showing a list of users who liked the post is going to be fast, but showing a list of posts a user liked?
This is what would happen to your sites speed and performance:
Searching for posts by their post meta is very, very bad. I’ve seen sites running on huge servers crippled by just a handful of these. It’s a huge slowdown, the kind of query that could take 10-20 seconds if it finishes at all once you have more than a handful of posts.
In this case, you would face a new problem too, if you had chosen option 2, the very ability to find those posts would become an issue. Thus option 1 would be superior, but performance would still be terrible
A Marginally Superior Solution With the Opposite Tradeoff
Use user meta to store the post IDs, rather than post meta to store the user IDs. Still has issues, aka showing a list of users who liked or unlocked a post is now super expensive. But showing a user all the posts they’ve liked is fast.
The Real Solution, and a General Rule of Thumb
If you need to store something, and you need to search/find/filter or show posts that have this special information, use a taxonomy.
In this case, a taxonomy named unlocked_by
, where the term slug/name is the user ID that liked it.
Now your query is super fast:
$q = new WP_Query([
'unlocked_by' => get_current_user_id()
]);
In fact, it’s so fast, you don’t even need that query, WP created a post archive at /unlocked_by/2/
( I’m user number 2 btw ), assuming you enabled that.
You could even add the parameter via pre_get_posts
so it happens transparently.
The wp_get_object_terms
and wp_get_object_terms
functions are your friend here