写博客做的最多的事情就是对内容修修改改,就好像打补丁一样。而我又是那种十分懒惰的人,一篇文章可以写上好久,往往还不连续。所以日子一长,200篇不到的博客数据库却超过了3MB。数据库清理看来是不能拖了。

要清理wordpress,必须先分析wordpress的数据库结构:

wordpress的文章部分主要用到下面2张表:


mysql> show tables;
+--------------------------+
| Tables_in_alexblair_blog |
+--------------------------+
| wp_postmeta |
| wp_posts |
+--------------------------+
2 rows in set (0.00 sec)

这两张表的内容很丰富,今天我们只关心重点部分:(下同)

wp_postmeta 记录的是文章的附加状态,默认情况下,即使清空也对现有文章没有大的障碍。

wp_posts包含WordPress文章的正文、用户、时间、状态等信息,是清理工作的重点。

由于wp_postmeta这张表可有可无,所以我们把重点放在wp_post上,先看wp_post的结构。
mysql>show columns from wp_posts;
+-----------------------+---------------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+---------------------+------+-----+---------------------+----------------+
| ID | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| post_author | bigint(20) unsigned | NO | | 0 | |
| post_date | datetime | NO | | 0000-00-00 00:00:00 | |
| post_date_gmt | datetime | NO | | 0000-00-00 00:00:00 | |
| post_content | longtext | NO | | NULL | |
| post_title | text | NO | | NULL | |
| post_excerpt | text | NO | | NULL | |
| post_status | varchar(20) | NO | | publish | |
| comment_status | varchar(20) | NO | | open | |
| ping_status | varchar(20) | NO | | open | |
| post_password | varchar(20) | NO | | | |
| post_name | varchar(200) | NO | MUL | | |
| to_ping | text | NO | | NULL | |
| pinged | text | NO | | NULL | |
| post_modified | datetime | NO | | 0000-00-00 00:00:00 | |
| post_modified_gmt | datetime | NO | | 0000-00-00 00:00:00 | |
| post_content_filtered | text | NO | | NULL | |
| post_parent | bigint(20) unsigned | NO | MUL | 0 | |
| guid | varchar(255) | NO | | | |
| menu_order | int(11) | NO | | 0 | |
| post_type | varchar(20) | NO | MUL | post | |
| post_mime_type | varchar(100) | NO | | | |
| comment_count | bigint(20) | NO | | 0 | |
+-----------------------+---------------------+------+-----+---------------------+----------------+
23 rows in set (0.00 sec)

天哪,查看wp_posts表的结构后,发现项目太多了!

其实我们的目的很简单,就是去掉草稿、旧版本、预览以及一切没有展示在博客上的文章。

简单的说,所有非发布模式下的文章都可以被删除。

精简一下刚才看到的内容,下面的这些才是我们需要关注的:
mysql>
+-----------------------+---------------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+---------------------+------+-----+---------------------+----------------+
| ID | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| post_title | text | NO | | NULL | |
| post_status | varchar(20) | NO | | publish | |
| post_type | varchar(20) | NO | MUL | post | |
+-----------------------+---------------------+------+-----+---------------------+----------------+

ID对应用户名,不过是以编号的形式出现的,这些用户编号存放在wp_users里,你可以通过
select id,user_login,user_nicename from wp_users;
的方法去获得

post_status是很关键的一个项目,它记录着文章的状态,默认值是publish也就是已发布。

好了,关键就在这里了。

我们只需要删除所有post_status不是publish值的项目就可以了。

等等,别高兴太早!wp_post表中的内容一定是文章么?不一定!

不少网上的文章都主张将非publish状态的记录都删除,这是很危险的一种操作,同时也是绝对错误的!

关键在于post_type,wp_post内除了文章之外,还有link、page等内容,如果一并删除,等于将未保存的链接或者草稿状态的页面等都一块删除了,这对于多用户的wordpress来说,后果是严重的。

mysql>select id,post_title,post_status,post_type from wp_posts where post_type!='post' limit 8;
+-----+------------------------------+-------------+-----------+
| id | post_title | post_status | post_type |
+-----+------------------------------+-------------+-----------+
| 198 | ?? | publish | page |
| 201 | ?? | publish | page |
| 203 | ?? | publish | page |
| 205 | ?? | publish | page |
| 344 | ?? | publish | page |
| 486 | WordPress ????????wp_posts?? | inherit | revision |
| 487 | WordPress ????????wp_posts?? | inherit | revision |
| 488 | WordPress ????????wp_posts?? | inherit | revision |
+-----+------------------------------+-------------+-----------+
8 rows in set (0.00 sec)

所以,安全的删除语句应该是这样的

mysql>delete from wp_posts where post_type='post' && post_status!='publish';
mysql>delete from wp_posts where post_type='revision' && post_status!='publish';

因为删除无法撤销,所以依然建议用下面的语句先进行查询确认

mysql>select id,post_title,post_status,post_type from wp_posts where post_type='post' && post_status!='publish';
mysql>select id,post_title,post_status,post_type from wp_posts where post_type='revision' && post_status!='publish';

3 Comments

  • 沿阶草说道:

    说的太专业了 看不懂。。。

  • komi说道:

    还可以吧,呵呵,写的挺好

  • sdwx说道:

    似乎很难啊 慢慢学习吧

  • 发表回复