写博客做的最多的事情就是对内容修修改改,就好像打补丁一样。而我又是那种十分懒惰的人,一篇文章可以写上好久,往往还不连续。所以日子一长,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'; |