WordPress 数据库清理手记(wp_posts篇)

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

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

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

1
2
3
4
5
6
7
8
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的结构。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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表的结构后,发现项目太多了!

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

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

精简一下刚才看到的内容,下面的这些才是我们需要关注的:

1
2
3
4
5
6
7
8
9
 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里,你可以通过

1
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来说,后果是严重的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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)

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

1
2
mysql>DELETE FROM wp_posts WHERE post_type='post' && post_status!='publish';
mysql>DELETE FROM wp_posts WHERE post_type='revision' && post_status!='publish';

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

1
2
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';

Related posts

《WordPress 数据库清理手记(wp_posts篇)》有3个想法

发表评论