[PR] 本記事にはプロモーションが含まれています。

【MariaDB】コピペで動かしていたWordPressのデータベースのコマンドを、意味から理解する|控え・確認・一括変更

MySQL

【2026年10月15日時点の情報です】

このブログは、自宅のAlmaLinuxサーバーでWordPressを動かしています。記事の書き直しやサイトの整理では、AI(Claude)に教わりながら、データベースを操作するコマンドを何十回も実行してきました。

ただ、正直に言うと、言われるがままにコピーして貼り付けていただけで、何をしているのかはほとんど分かっていませんでした。それでは、何かあったときに自分で判断できません。

そこで、実際に使ってきたコマンドを、場面ごとに「何のためか」「それぞれの部分にどんな意味があるか」から整理しました。同じように、コピペでデータベースを触っている人の参考になればうれしいです。

WordPressのデータはどこにあるのか

WordPressの記事やカテゴリー、設定は、ファイルではなくデータベースに入っています。このブログでは、データベースのソフトにMariaDB(MySQLとほぼ同じ使い方ができるもの)を使っています。

データベースの中は、Excelの表のような「テーブル」に分かれています。よく使ったのは次の4つです。

テーブル入っているもの例
wp_posts記事・固定ページ・画像の登録などタイトル(post_title)、本文(post_content)、スラッグ(post_name)、状態(post_status)
wp_postmeta記事や画像に付いた追加の情報アイキャッチの画像ID(_thumbnail_id)、画像のファイルの場所(_wp_attached_file)、メタディスクリプション
wp_optionsサイト全体の設定テーマの設定、ウィジェットの中身
wp_terms などカテゴリーやタグカテゴリーの名前とスラッグ

記事も画像も、wp_posts の1行として登録されています。どちらなのかは、post_type という列(記事なら post、画像なら attachment)で見分けます。

コマンドの入り口

どのコマンドも、まず次の形から始まっています。

Bash
sudo mysql wordpress -e "SELECT ...;"
  • sudo:
    管理者の権限で実行する。このサーバーのMariaDBは、管理者(root)でログインするときに、パスワードの代わりにLinuxの管理者の権限で確かめる設定になっているため
  • mysql:
    データベースに命令を送るためのプログラム
  • wordpress:
    使うデータベースの名前
  • -e “…”:
    「この文字の命令を1回だけ実行して終わる」という意味。付けないと、命令を打ち込む画面が開いたままになる
  • -N(付けたときだけ):
    結果の一番上の列の名前を出さない。結果を、ほかのコマンドに渡して加工するときに使う

「SELECT …;」の部分がSQL(データベースへの命令の言葉)で、ここが場面ごとに変わります。

長いSQLのときは、次のような書き方もしました。

Bash
sudo mysql wordpress <<'SQL'
UPDATE ...;
SELECT ...;
SQL
  • <<‘SQL’ 〜 SQL:
    「ここから SQL と書いた行までを、まとめて mysql に渡す」という意味(ヒアドキュメント)。’SQL’ と引用符で囲むと、中の \ や $ をシェルが勝手に書き換えないので、正規表現などをそのまま書ける

場面1:変える前に、控えを取る

データベースを書き換えるコマンドは、WordPressの画面と違って「元に戻す」ボタンがありません。なので、書き換える前に必ず控え(バックアップ)を取っていました。

データベースの控え

Bash
sudo mysqldump wordpress > ~/work/backup/wordpress-20261015.sql
sudo mysqldump wordpress wp_posts > ~/work/backup/wp_posts-20261015.sql
  • mysqldump:
    データベースの中身を、作り直せる形のSQLの文字にして書き出すプログラム
  • wordpress:
    控えを取るデータベースの名前。1行目のように名前だけなら、全部のテーブル
  • wp_posts(2行目):
    テーブルの名前を続けると、そのテーブルだけの控えになる。記事の本文だけを書き換えるときは、これで十分で、ファイルも小さくて済む
  • >:
    画面に出る結果を、右のファイルに書き込む

画像ファイルの控え

画像はデータベースではなく、サーバーのフォルダに入っているので、別に控えを取ります。

Bash
sudo tar czf ~/work/backup/uploads-20261015.tar.gz -C /var/www/html/wp-content uploads
  • tar:
    複数のファイルやフォルダを1つのファイルにまとめるプログラム
  • czf:
    c(まとめる)、z(圧縮する)、f(次に書いた名前のファイルにする)
  • -C /var/www/html/wp-content uploads:
    「wp-content のフォルダに移動してから、uploads のフォルダをまとめる」という意味。こうすると、控えの中のファイルの場所が uploads/… から始まるので、戻すときに扱いやすい

控えから戻す

全部を戻すときは、控えのSQLをそのまま mysql に流し込みます。

Bash
sudo mysql wordpress < ~/work/backup/wp_posts-20261015.sql
  • <:
    右のファイルの中身を、命令として左のプログラムに渡す(> の逆向き)

ただし、全部を戻すと、控えを取ったあとの変更も消えてしまいます。実際に、画像を3枚だけ間違えて消してしまったときは、次のように「一時的な別のデータベースに控えを読み込んで、必要な行だけを書き戻す」方法を使いました。

Bash
sudo mysql -e "CREATE DATABASE wp_restore;"
sudo mysql wp_restore < ~/work/backup/wordpress-20261015.sql
sudo mysql -e "
INSERT INTO wordpress.wp_posts SELECT * FROM wp_restore.wp_posts WHERE ID IN (474, 2923, 1197);
INSERT INTO wordpress.wp_postmeta SELECT * FROM wp_restore.wp_postmeta WHERE post_id IN (474, 2923, 1197);
DROP DATABASE wp_restore;"
  • CREATE DATABASE wp_restore:
    控えを読み込むための、空のデータベースを作る
  • INSERT INTO A SELECT * FROM B WHERE …:
    Bの表から条件に合う行を取り出して、Aの表に入れる。wordpress.wp_posts のように「データベース名.テーブル名」と書くと、別のデータベースどうしでやり取りできる
  • DROP DATABASE wp_restore:
    使い終わった一時的なデータベースを消す

場面2:記事を探して、編集画面のURLを出す

「この記事を直したい」というときに、記事のスラッグから、編集画面のURLを出していました。

Bash
sudo mysql wordpress -N -e "SELECT CONCAT('https://softdev-learn.cc/wp-admin/post.php?post=', ID, '&action=edit'), post_name FROM wp_posts WHERE post_type = 'post' AND post_status = 'publish' AND post_name IN ('pc-spec','home-server');"
  • SELECT 列, 列 FROM テーブル:
    テーブルから、指定した列を取り出す。SQLの一番基本の形
  • CONCAT(…):
    文字をつなげる。ここでは、編集画面のURLの前半+記事のID+後半をつなげて、そのまま開けるURLにしている
  • WHERE 条件:
    条件に合う行だけを取り出す。AND でつなぐと「全部の条件に合うもの」
  • post_type = ‘post’:
    記事だけ(画像や固定ページを除く)
  • post_status = ‘publish’:
    公開中だけ(下書きは draft、非公開は private)
  • post_name IN (‘…’,’…’):
    スラッグが、かっこの中のどれかに当てはまるもの

場面3:本文の中の文字を探す

本文に特定の文字が残っていないかを探すときの形です。例えば、記事の書き直しのメモ「【画像:」が、公開中の記事に残っていないかを探すときは、次のようにします。

Bash
sudo mysql wordpress -e "SELECT ID, post_name FROM wp_posts WHERE post_type = 'post' AND post_status = 'publish' AND post_content LIKE '%【画像:%';"
  • LIKE ‘%…%’:
    「この文字を含む」という意味。% は「何でもよい文字が0文字以上」の印で、前後に付けると「途中のどこかに含む」になる

見つかった文字の前後だけを見たいときは、次の形にしました。

Bash
sudo mysql wordpress -N -e "SELECT SUBSTRING(post_content, LOCATE('3周年', post_content) - 200, 400) FROM wp_posts WHERE ID = 2563;"
  • LOCATE(‘文字’, 列):
    その文字が、何文字目に出てくるかを返す
  • SUBSTRING(列, 始め, 長さ):
    始めの位置から、指定した長さだけ取り出す。ここでは、見つかった位置の200文字前から400文字を出している

このとき、文字が見つからないと LOCATE は 0 を返すので、記事の一番最後の部分が表示されます。実際に「3周年の文がどこにあるか」を探したときは、記事の最後が出てきたので、もう消えていると分かりました。

場面4:別のテーブルとつなげて見る(アイキャッチのファイル名)

記事のアイキャッチの画像のURLを一覧にしたいとき、1つのテーブルだけでは分かりません。

テーブル分かること
wp_postmeta(記事の _thumbnail_id)記事に付いているアイキャッチの画像のID
wp_postmeta(画像の _wp_attached_file)その画像のファイルの場所

この2つを、JOIN でつなげます。

Bash
sudo mysql wordpress -e "
SELECT p.ID, p.post_name, CONCAT('https://softdev-learn.cc/wp-content/uploads/', f.meta_value) AS eyecatch
FROM wp_posts p
JOIN wp_postmeta t ON t.post_id = p.ID AND t.meta_key = '_thumbnail_id'
JOIN wp_postmeta f ON f.post_id = t.meta_value AND f.meta_key = '_wp_attached_file'
WHERE p.post_name IN ('nomu-yoguret-review','vscode-profile');"
  • wp_posts p:
    テーブルに p という短い呼び名を付ける。同じ wp_postmeta を2回使うので、t と f で呼び分けている
  • JOIN 表 ON 条件:
    条件に合う行どうしを横につなげる。1つ目は「記事のID=メタの post_id、かつメタの種類がアイキャッチ」、2つ目は「アイキャッチの画像ID(t.meta_value)=画像のメタの post_id、かつ種類がファイルの場所」
  • AS eyecatch:
    結果の列に名前を付ける

つまり、「記事 → アイキャッチの画像ID → 画像のファイルの場所」と、2回たどっています。

数える・まとめる

カテゴリーごとの記事の数や、404の多いURLを出すときは、数える命令を使いました。

Bash
sudo mysql wordpress -e "
SELECT url, COUNT(*) AS hits, MAX(created) AS last
FROM wp_redirection_404
WHERE created > NOW() - INTERVAL 30 DAY
GROUP BY url HAVING hits >= 2
ORDER BY hits DESC LIMIT 30;"
  • wp_redirection_404:
    プラグイン Redirection が記録している「ページが見つからなかったアクセス」のテーブル
  • GROUP BY url:
    同じURLの行を1つにまとめる
  • COUNT(*):
    まとめた行の数(ここではアクセスの回数)
  • MAX(created):
    まとめた中で一番新しい日時(最後のアクセス)
  • NOW() – INTERVAL 30 DAY:
    今から30日前。それより新しいものだけにする
  • HAVING hits >= 2:
    まとめたあとの条件。2回以上のものだけ(WHERE はまとめる前、HAVING はまとめたあとの条件)
  • ORDER BY hits DESC LIMIT 30:
    回数の多い順(DESC)に並べて、上から30行だけ

場面5:まとめて書き換える(UPDATE)

ALTERNAのカテゴリーの場所を変えたとき、5本の記事の本文に入っていた古いカテゴリーのURLを、新しいURLにまとめて置き換えました。

Bash
sudo mysql wordpress -e "
UPDATE wp_posts
SET post_content = REPLACE(post_content, '/category/investment/estate-crowd/alterna/', '/category/investment/digital_securities/alterna/')
WHERE post_type = 'post' AND post_content LIKE '%/category/investment/estate-crowd/alterna/%';
SELECT ROW_COUNT();"
  • UPDATE テーブル SET 列 = 値 WHERE 条件:
    条件に合う行の、列の中身を書き換える。WHERE を付け忘れると、全部の行が書き換わるので一番注意するところ
  • REPLACE(列, ‘古い文字’, ‘新しい文字’):
    列の中の、古い文字を全部、新しい文字に置き換えた結果を返す
  • WHERE … LIKE ‘%古いURL%’:
    古いURLを含む記事だけを対象にする(含まない記事は書き換えない)
  • SELECT ROW_COUNT():
    直前の命令で、何行が変わったかを出す。思った数(このときは5)と合っているかを確かめる

書き換える前に、同じ条件で数える

UPDATE の前には、同じ WHERE の条件で SELECT して、対象が何件かを確かめていました。

Bash
sudo mysql wordpress -e "SELECT ID, post_name FROM wp_posts WHERE post_type = 'post' AND post_content LIKE '%/category/investment/estate-crowd/alterna/%';"

この一覧が思ったとおりなら、同じ条件で UPDATE します。SELECT と UPDATE で条件を同じにしておけば、「思っていない記事まで書き換えた」ということが起きません。

場面6:別の値を使って書き換える(アイキャッチの一括差し替え)

カテゴリーの共通のアイキャッチを、タイトルを入れた新しい画像に替えたときは、38本の記事のアイキャッチを、1回のコマンドで差し替えました。

Bash
sudo mysql wordpress <<'SQL'
SET @n1 = (SELECT post_id FROM wp_postmeta WHERE meta_key = '_wp_attached_file' AND meta_value LIKE '%category-estate-crowd%' ORDER BY post_id DESC LIMIT 1);
SELECT @n1;
UPDATE wp_postmeta SET meta_value = @n1 WHERE meta_key = '_thumbnail_id' AND meta_value = '3669' AND @n1 IS NOT NULL;
SQL
  • SET @n1 = (SELECT …):
    @ で始まる名前は、SQLの中で使える一時的な入れ物(変数)。ここでは、新しくアップロードした画像のIDを、ファイル名から探して入れている。IDを調べて手で書き写さなくて済む
  • ORDER BY post_id DESC LIMIT 1:
    同じ名前のファイルが複数あったときに、一番新しい(IDが大きい)1つにする
  • SELECT @n1:
    見つかったIDを画面に出して、合っているか確かめる
  • WHERE meta_key = ‘_thumbnail_id’ AND meta_value = ‘3669’:
    アイキャッチが古い画像(3669)になっている記事だけを対象にする
  • AND @n1 IS NOT NULL:
    新しい画像が見つからなかったとき(@n1 が空)は、何も書き換えない。アイキャッチが空になる事故を防ぐ

行を消してから入れ直す(メタディスクリプションの一括登録)

メタディスクリプションがない22本に、まとめて登録したときは、記事ごとに次の2行を並べたファイルを作って、流し込みました。

SQL
DELETE FROM wp_postmeta WHERE post_id = 704 AND meta_key = 'the_page_meta_description';
INSERT INTO wp_postmeta (post_id, meta_key, meta_value) VALUES (704, 'the_page_meta_description', 'Webページの骨組みを作るHTMLの基本を…');
  • DELETE FROM … WHERE …:
    条件に合う行を消す。空のメタディスクリプションの行が残っていると、2つ並んでしまうので、先に消している
  • INSERT INTO テーブル (列, 列, 列) VALUES (値, 値, 値):
    新しい行を1つ追加する。the_page_meta_description は、テーマ Cocoon がメタディスクリプションを入れておく場所の名前

ファイルにしたSQLは、場面1の「戻す」と同じく < で流し込みます。

言語:bash

sudo mysql wordpress < ~/work/meta-desc-20261015.sql

結果を加工する、シェルの道具

SQLの結果を、そのまま読むのではなく、ほかのコマンドに渡して加工することもよくありました。

Bash
sudo mysql wordpress -N -e "SELECT post_content FROM wp_posts WHERE post_name = 'cofo-chair-premium';" | grep -oE "softdev-learn\.cc/[a-z0-9_-]+/" | sort -u
  • |(パイプ):
    左のコマンドの結果を、右のコマンドに渡す
  • grep -oE “…”:
    文字を探す。-o は「見つかった部分だけを出す」、-E は「正規表現(文字の並びの決まりを記号で書く方法)を使う」
  • softdev-learn.cc/[a-z0-9_-]+/:
    「softdev-learn.cc/」のあとに、英小文字・数字・_・- が1文字以上続いて、/ で終わるもの(つまり、このブログの記事のURL)。. は「本当のピリオド」という意味(. だけだと「何でもよい1文字」になる)
  • sort -u:
    並べ替えて、同じものを1つにまとめる

このほかに、次のような道具を組み合わせました。

道具使い方
wc -l行の数を数える(何件あったかを確かめる)
head -20最初の20行だけを見る
for 名前 in A B C; do …; doneA・B・C のそれぞれで、同じコマンドをくり返す(複数の記事を順に調べる)
curl -sI URLページを開いたときの返事の見出しだけを出す。301(転送)か404(見つからない)かの確認に使った

安全に操作するために決めていること

コマンドの意味が分かってくると、事故が起きやすい場所も見えてきました。今は、次の5つを守っています。

  • 書き換える前に、必ず控えを取る:
    mysqldump で、少なくとも書き換えるテーブルの控えを取る
  • 書き換える前に、同じ条件で SELECT する:
    対象が思った記事・思った件数かを確かめてから UPDATE する
  • WHERE を必ず付ける:
    UPDATE や DELETE で WHERE を忘れると、全部の行が変わる
  • 変わった件数を確かめる:
    ROW_COUNT() や、変更後の SELECT で、件数が思ったとおりかを見る
  • 一部だけ間違えたときは、一部だけ戻す:
    控えを別のデータベースに読み込んで、必要な行だけを書き戻す

まとめ

コピペで動かしていたコマンドも、分けてみると、使っていたSQLは SELECT(見る)、UPDATE(書き換える)、INSERT・DELETE(行を足す・消す)の4つがほとんどでした。そこに、WHERE(どの行か)、JOIN(ほかのテーブルとつなぐ)、REPLACE(文字の置き換え)などを組み合わせているだけです。

意味が分かると、AIが出したコマンドでも、「この WHERE で本当にこの記事だけが対象になるか」「控えは取ったか」を、自分で確かめられるようになります。データベースを直接さわるのは便利な反面、元に戻すボタンがないので、控えと確認だけは習慣にするのがおすすめです。

このコマンドを使って、実際に WordPress の困りごとを直した話は、SQL で記事を下書きに戻したら空のカテゴリーが出た件の記事と、Redirection のルールが保存されなかった件の記事に書いています。

自宅サーバーの構成は、自宅サーバー構築メモにまとめています。

この記事は、シリーズ「組み込みエンジニアの Web 開発入門」の1本です。ほかの回は、シリーズの目次からどうぞ。

ほかの開発・プログラミングの記事は、開発・プログラミングメモの目次から、テーマ別に探せます。

このブログは、にほんブログ村と人気ブログランキングに参加しています。記事が役に立ったら、下のランキングのバナーのどれかを押して応援してもらえると励みになります。

ブログランキング・にほんブログ村へにほんブログ村

サーバー構築・運用ランキング プログラムランキング

MySQL
watasoftdevをフォローする

コメント