WordPress開発:記事関連データベース基本構造と検索解析

WordPress開発:記事関連データベース基本構造と検索解析

 みなさんこんにちは、ALL CONNECT デザイン本部開発部の楊です。
 初めての投稿でまだまだ未熟でございますが、お読み頂ければ幸いです。
 この度はブログ作成用システム WordPress のデータベースの記事関連部分について紹介したいと思います。

標準インストールの WordPress 基本テーブル関連

 Wordpressを標準インストールするとき、自動的にデータベースを作成し、そのデータベースと連動することができます。
 エンドユーザーはその構造を気にする必要はありませんが、開発者としてよりに自由自在にWordpressを利用するため、やはりその構造を把握する必要があると思います。

 下図は、WordPressデータベースの概要および標準インストール時に作成されるテーブル間の関係を視覚的に表したものです。

 
 投稿関連のは下記テーブルです。

テーブル一覧
wp_postsWordPress データの核である投稿記事、固定ページなどのデータを格納
wp_postmetaメタデータという各投稿記事特有の情報を格納。カスタムフィールドとして使用するほか、各投稿に情報や設定を付加するようなプラグインが、その情報を当テーブルに追加することがある。
wp_term_relationshipswp_posts テーブルの各投稿記事と wp_term_taxonomy のカテゴリ・タグとの関連付け情報を格納
wp_term_taxonomy投稿およびリンクの分類上の語句(カテゴリ・タグ)データを格納
wp_terms投稿およびリンクの分類(カテゴリ・タグ)に使われる語句の基本情報を格納

独特のデータ保存方法

 通常のデータベースの同じ特徴があるデータを同じテーブルで格納する方法と違って、Wordpress のデータベースはすべての核となる情報を、投稿や固定ページなどかかわらず、全部投稿の概念で wp_posts に保存して、その分類(カテゴリ、タグ)やプロパティ(メータ情報)などその用途によって、wp_postmeta や wp_terms などのテーブルに保存します。

 たとえば、通常では下記のように保存されているデータ:

テーブル一:果物テーブル t_fruit
namecolorweight
リンゴ200
バナナ150
レモン100
テーブル二:本テーブル t_book
titlelanguageauthorprice
コンプリート・シャーロック・ホームズ日本語アーサー・コナン・ドイル5000
戦争と平和日本語レフ・トルストイ6000
復活ロシア語レフ・トルストイ4000

 Wordpress の場合、果物も本も全部投稿になって、果物や本をカスタム投稿タイプとして wp_posts に保存します。

wp_posts (一部省略)
IDpost_titlepost_statuspost_namepost_type
1リンゴpublishapplefruit
2バナナpublishbananafruit
3レモンpublishlemonfruit
4コンプリート・シャーロック・ホームズpublishthe_complete_sherlock_holmesbook
5戦争と平和publishwar_and_peacebook
6復活publishresurrectionbook

 本の言語や果物の色をカテゴリやタグと同様に wp_terms に保存します。

wp_terms
term_idnameslugterm_group
1red0
2yellow0
3日本語japanese0
4ロシア語russian0

 その分類は wp_term_taxnomy に保存します。

wp_term_taxnomy
term_taxonomy_idterm_idtaxonomydescriptionparentcount
11color01
22color02
33language02
44language01

 そして wp_term_relationships で記事とその分類をつながります。

wp_term_relationships
object_idterm_taxonomy_idterm_order
110
220
320
430
530
640

 最後に他の詳細情報を wp_postmeta に保存します。

wp_postmeta
meta_idpost_idmeta_keymeta_value
11price200
22price150
33price100
44authorアーサー・コナン・ドイル
54price5000
65authorレフ・トルストイ
75price6000
86authorレフ・トルストイ
96price4000

 一見 WordPress の場合同じ量の情報を保存するため、使うテーブルの数もデータの量も多いで、通常のデータベースより使い勝手が悪く思われますが、しかし WordPress のデータベースの強さはデータを拡張するときの自由さです。

 例えばさっきの例で本にページ数の情報を追加した場合、通常のデータベースなら開発者がデータベースで t_book の構造を変えて、page_number のカラムを追加しなければなりません。

改修後本テーブル t_book
titlelanguageauthorpricepage_number
コンプリート・シャーロック・ホームズ日本語アーサー・コナン・ドイル5000250
戦争と平和日本語レフ・トルストイ6000300
復活ロシア語レフ・トルストイ4000200

 Wordpress のデータベースならそのテーブル構造に変更は要りません、ただ wp_postmeta で行を増やすだけで、その改修ができます。

wp_postmeta
meta_idpost_idmeta_keymeta_value
・・・・・・
104page_number250
115page_number300
126page_number200

 そしてプラグイン「Advanced Custom Fields」を搭載している WordPress に対して、この作業は管理画面だけで行うことができます、データベースでの操作は一切必要ありません。

特定情報の絞込み――Wordpress データベースの select 文

 Wordpress のデータは各テーブルに分散で保存していますから、特定の記事を取得するために通常複数のテーブルをJOINで繋がって、記事情報を取ります。その目標の情報によって、時に複雑な select 文になります。
 実際に WordPress で開発するとき、データの取得は get_posts() や get_category() など WordPress が提供する関数で簡単に取得することができますが、やはり一人の開発者として WordPress のデータはどう取得されているかを理解する必要があると思います。

 Wordpress の select 文を書くために、まず WordPress データベースの各テーブルの関連性を理解する必要があります。
 本文最初のER図をもう一度見ましょう。

 
 図から簡単に理解できますが、核として使われているwp_postsから出発して、前に紹介した記事関連のテーブルは全部繋がることができます。

wp_postmeta
テーブルAテーブルB関連性
wp_postswp_postmetawp_posts.ID = wp_postmeta.post_id
wp_postswp_term_relationshipswp_posts.ID = wp_term_relationships.object_id
wp_term_relationshipswp_term_taxonomywp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
wp_term_taxonomywp_termswp_term_taxonomy.term_id = wp_terms.term_id

では前に使った本と果物の例で練習しましょう。

目標:「レフ・トルストイ」作の「日本語」の本の情報を通常のデータベースのフォーマットで取得

 まず select 部分から作りましょう。
 必要は情報は本のタイトル、言語、作者、値段、ページ数。
 その内タイトルは wp_posts から取得できます、作者、値段とページ数は wp_postmeta から取得できます、言語は wp_terms から取得できます。

 次は where の部分です。
 「日本語」の本ですから、wp_terms.name = ‘日本語’、そして wp_term_taxonomy.taxonomy = ‘language’です。
 作者は「レフ・トルストイ」ですから、wp_postmeta.meta_value = ‘レフ・トルストイ’、そして wp_postmeta.meta_key = ‘author’です。

 最後に from の部分作りましょう。
 まずタイトルを取得しますから、wp_posts は必要です。
 次に作者、値段とページ数を取得しますから、wp_postmeta は三つが必要です。
 最後に言語を条件にする必要がありますから、wp_terms と wp_term_taxonomy が必要です。しかし wp_term_taxonomy は wp_posts と直接繋がることができませんから、wp_term_relationships も必要となります。

 結果、下記 SQL 文が作成されました。

 その検索結果は下記です。

検索結果
titlelanguageauthorpricepage_number
戦争と平和日本語レフ・トルストイ6000300

 いかがでしたでしょうか?Wordpress のデータベース構造と select 文の方法はお分かりいただけましたでしょうか?


Previous: MySQLのテーブルにCSVデータをINSERTする場合はLOCALパラメータを使う Next: PHPで即時関数を実行して可読性アップ!call_user_func の使い方

© 2017 ALL CONNECT Inc. All Rights Reserved.