简洁的PHP博客系统-Typecho
Typecho 是由 type 和 echo 两个词合成的,来自于开发团队的头脑风暴。这是一款仿WordPress,但相对其要简单的多的开源博客程序。开发者大量的参考了WordPress的设计,去除了一些高级复杂的功能,实现了一个小而美的博客系统。Type,有打字的意思,博客这个东西,正是一个让我们通过打字,在网络上表达自己的平台。Echo,意思是回声、反馈、共鸣,也是PHP里最常见、最重要的函数,相信大部分PHP爱好者都是从 echo 'Hello,world!'; 开始自己的PHP编程之路的。
名称就表明 Typecho 是一款博客程序,它在 GPLv2 许可证下发行,基于 PHP (需要 PHP5 以上版本)构建,可以运行在各种平台上,支持多种数据库(Mysql, PostgreSQL, SQLite)。
源自开发团队在精神层面上的洁癖和狂热。在使用博客程序的大部分时间里,我们只是发几段文字,贴几张图片,不需要高级复杂的系统,需要的是一个简单快速的博客平台。在流行的开源程序中,满足我们要求的很少,于是我们决定自己动手,开发一款有性格的博客程序并在开源协议下发行。开发团队中的几个人都是 IT 从业者,在成长的过程中从开源世界里获益匪浅,这个项目也是我们对开源的一个回报。
优点:
轻量高效:仅仅 7 张数据表,加上不足 400KB 的代码,就实现了完整的插件与模板机制。超低的 CPU 和内存使用率,足以发挥主机的最高性能。
先进稳定:原生支持 Markdown 排版语法,易读更易写。支持 BAE/GAE/SAE 等各类云主机,即使面对突如其来的高访问量,也能轻松应对。
简洁友好:精心打磨过的操作界面,依然是你熟悉的面孔,更多了一份成熟与贴心。每一个像素的剪裁,都只为离完美更进一步。
在商业网站中使用
可以自由地在商业网站中使用Typehco,而不必为此交纳其它的费用。
基于Typecho的二次开发
如果二次开发后的代码是开源的,请遵守GPLv2协议分发。
如果你的二次开发代码是闭源且商用的,请遵循如下原则,并将其附加到您的软件说明书中告知用户:
1、此软件基于免费开源的 Typecho。
2、软件中的 Typecho 软件著作权独立于本软件的其它部分,归属 Typecho 团队所有(你可以选择将Typecho部分和你开发的部分一起分发给用户,但在安装包中的文件组织上,必须将两者分开,其中 Typecho 部分必须为官方发布的完整文件包,文件或者目录名为 "Typecho"。可以在安装之后用你的相关文件替换原包中的文件)。
3、Typecho 团队不为任何使用了二次分发代码的用户提供咨询,解释,以及其它附加服务。
4、Typecho 团队不为任何二次分发代码的安全性,可用性,完整性以及其可能带来的其它风险及损失承担责任。
5、所有在最终分发的商业软件包中包含了 Typecho,但没有告知用户以上事项者被视为非法使用,Typecho 团队保留追究其相关法律责任的权利。
团队
Typecho 的前身是一个款叫做 Magike 的开源博客程序,是由 Typecho 项目的发起人 70 开发的。Typeche 团队的最初形成,是在第一次 WordCamp China 的活动上,后来有更多志同道合的成员加入了这个充满朝气的项目,才有了现在的 Typecho。团队成员来自天南地北,遵循敏捷开发的思路,通过邮件、IM 沟通并制订开发计划,利用工作之余的闲暇时间完成各种工作。
仅仅 7 张数据表,加上不足 400KB 的代码,就实现了完整的插件与模板机制。超低的 CPU 和内存使用率,足以发挥主机的最高性能。一起来看下7张表的数据库的数据库设计,看从中能学到什么。
设计思路
Typecho的定位是单用户blog系统,当在设计一个单用户blog系统时要时刻把“单用户”这三个字放在心上。单用户意味着数据的查询是很集中的,当一个用户页面的访问量比较小时他几乎感觉不到多出的几次查询带来多少延迟。而当访问量比较大时他必然有实力去升级他的系统。由于单用户系统的查询比较集中,可以通过部署文件缓存或者内存对象缓存来达到减轻数据库压力的目的,或者增加数据库数量来达到平滑的系统扩容。因此单用户系统设计重点在于灵活性和结构化。
5张表的设计
列举一下一个blog系统需要哪些元素,这样也可以让我们更好地设计数据库表。除了文章、评论、分类、用户、链接外,还有文件、标签、链接分类、多重分类。如果考虑到系统的灵活性,还需要将所有的可配置选项放到一个表中,类似于wordpress的options表。清点一下这些表:
文章表
评论表
文章分类表
标签表
链接表(友情链接)
链接分类表
文章与分类映射表(一对多)
文章与标签映射表(一对多)
配置表
用户表
文件表
一共11张表,虽然不是很多但是总觉得还有抽象的余地。当仔细观察它们之间的关系后,除了配置表和用户表之外。其它表之间的关系都可以抽象为内容与项目之间的关系(可能是一对一,可能是一对多)。通过这个抽象,我们可以把剩下的表缩减为3个表,那么来看看第二版数据库结构:
内容表
关系表
项目表
配置表
用户表
根据以上设计以及我们的经验,只需要精心设计内容表和项目表的表结构就可以形成丰富的扩展应用。项目表与内容表的对应形成了对内容的修饰。由于有了关系表的存在内容与项目的关系可以是一对一也可以是一对多。
6张表的设计
如果你仔细分析一下上面的设计,你会发现一个隐藏的问题,那就是评论表的定义。显然评论表不可能是项目表,那么他只可能是内容表,但内容与内容之间的关系是我们以上设计中所没有定义的。观察评论与内容的关系:
评论从属于内容,无法单独存在
评论与内容是多对一的关系,且一条评论只能对应于一个内容
评论的数量往往比较大,对于访问量比较大的blog。其单篇文章的评论往往要达到上百篇。
根据以上考虑,评论表应该单独形成一个表与内容区分开。且根据常规做法以及速度上的考虑,评论应该用一个保留字段保存其从属内容的主键以便查询。那么第三版数据库结构就出炉了。
内容表
关系表
项目表
评论表
配置表
用户表
梳理设计
内容表可以扩展出来的类型
post(文章)
draft(草稿)
page(页面)
link(链接)
attachment(文件)
项目表里的类型
category(分类)
tag(标签)
link_category(链接分类)
表以及字段命名
考虑到标准化和国际化的需要,在表以及字段设置上应该尽量使用标准名称。而由于使用了一对多的关系映射,在可以预见的地方内容与项目之间都不可能使用联合查询,而是用多次*联动查询*,来取出多行关联数据。所以内容表与项目表的字段是可以重名的(在联合查询中,重名字段会被覆盖)。以下是对各数据表的命名:
内容表 – contents
关系表 – relationships
项目表 – metas(meta的意思为关于什么的什么)
评论表 – comments
配置表 – options
用户表 – users
Typecho数据字典
contents表
| 键名 | 类型 | 属性 | 解释 |
| cid | int(10) | 主键,非负,自增 | post表主键 |
| title | varchar(200) | 可为空 | 内容标题 |
| slug | varchar(200) | 索引,可为空 | 内容缩略名 |
| created | int(10) | 索引,非负,可为空 | 内容生成时的GMT unix时间戳 |
| modified | int(10) | 非负,可为空 | 内容更改时的GMT unix时间戳 |
| text | text | 可为空 | 内容文字 |
| order | int(10) | 非负,可为空 | 排序 |
| authorId | int(10) | 非负,可为空 | 内容所属用户id |
| template | varchar(32) | 可为空 | 内容使用的模板 |
| type | varchar(16) | 可为空 | 内容类别 |
| status | varchar(16) | 可为空 | 内容状态 |
| password | varchar(32) | 可为空 | 受保护内容,此字段对应内容保护密码 |
| commentsNum | int(10) | 非负,可为空 | 内容所属评论数,冗余字段 |
| allowComment | char(1) | 可为空 | 是否允许评论 |
| allowPing | char(1) | 可为空 | 是否允许ping |
| allowFeed | char(1) | 可为空 | 允许出现在聚合中 |
relationships表
| 键名 | 类型 | 属性 | 解释 |
| cid | int(10) | 主键,非负 | 内容主键 |
| mid | int(10) | 主键,非负 | 项目主键 |
metas表
| 键名 | 类型 | 属性 | 解释 |
| mid | int(10) | 主键,非负 | 项目主键 |
| name | varchar(200) | 可为空 | 名称 |
| slug | varchar(200) | 索引,可为空 | 项目缩略名 |
| type | varchar(32) | 可为空 | 项目类型 |
| description | varchar(200) | 可为空 | 选项描述 |
| count | int(10) | 非负,可为空 | 项目所属内容个数 |
| order | int(10) | 非负,可为空 | 项目排序 |
comments表
| 键名 | 类型 | 属性 | 解释 |
| coid | int(10) | 主键,非负,自增 | comment表主键 |
| cid | int(10) | 索引,非负 | post表主键,关联字段 |
| created | int(10) | 非负,可为空 | 评论生成时的GMT unix时间戳 |
| author | varchar(200) | 可为空 | 评论作者 |
| authorId | int(10) | 非负,可为空 | 评论所属用户id |
| ownerId | int(10) | 非负,可为空 | 评论所属内容作者id |
| varchar(200) | 可为空 | 评论者邮件 | |
| url | varchar(200) | 可为空 | 评论者网址 |
| ip | varchar(64) | 可为空 | 评论者ip地址 |
| agent | varchar(200) | 可为空 | 评论者客户端 |
| text | text | 可为空 | 评论文字 |
| type | varchar(16) | 可为空 | 评论类型 |
| status | varchar(16) | 可为空 | 评论状态 |
| parent | int(10) | 可为空 | 父级评论 |
options表
| 键名 | 类型 | 属性 | 解释 |
| name | varchar(32) | 主键 | 配置名称 |
| user | int(10) | 主键,非负 | 配置所属用户,默认为0(全局配置) |
| value | text | 可为空 | 配置值 |
users表
| 键名 | 类型 | 属性 | 解释 |
| uid | int(10) | 主键,非负,自增 | user表主键 |
| name | varchar(32) | 唯一 | 用户名称 |
| password | varchar(32) | 可为空 | 用户密码 |
| varchar(200) | 唯一 | 用户的邮箱 | |
| url | varchar(200) | 可为空 | 用户的主页 |
| screenName | varchar(32) | 可为空 | 用户显示的名称 |
| created | int(10) | 非负,可为空 | 用户注册时的GMT unix时间戳 |
| activated | int(10) | 非负,可为空 | 最后活动时间 |
| logged | int(10) | 非负,可为空 | 上次登录最后活跃时间 |
| group | varchar(16) | N/A | 用户组 |
| authCode | varchar(40) | 可为空 | 用户登录验证码 |
最新版本:1.1
官方主页:http://typecho.org/