Django i18n国际化在windows测试环境中需要注意的问题

这两天准备把前面写的网站 春天音乐 做一下国际化

(补充:翻译量小,半天就完成了,不过教训是一开始应该预留翻译函数接口。在模板中找字符串浪费了很多时间),

以曾经的经验,这样的资源站,超过一半的访客都是通过google进入的,国外用户数高于内地访客。

在windows开发环境中测试i18n可能会遇到一些问题,此处简单罗列:

1. 在windows下安装gnu gettext

i18n需要使用到gettext,windows下单独编译或安装。

当前我win7上所用的django版本为1.5.1,它要求提供至少提供0.15以上的gettext

附0.17的win32安装包: gettext-0.17-win32-setup.exe

安装完毕之后,请把子文件夹bin添加到用户的环境变量PATH中。

 

2. 让locale文件夹位于app目录下

django-admin.py makemessages -l en

上述命令会自动搜寻 视图文件views.py、模板文件中需要翻译的中文字符串(此处我是中译英),

执行这个命令之前,可以首先切换到app目录下,创建一个locale文件夹。

执行后会自动生成en\LC_MESSAGES\django.po这样的文件,以及其上级父文件夹。

 

3. 在修改翻译之后,编译并重启web server

在我们修改了django.po中的翻译后,每次都需要执行:

django-admin.py compilemessages

编译它,随后会生成一个django.mo文件。

为了让修改生效,需要重启web服务器。

测试环境中使用WSGIServer同样需要重启。

下载翻译编辑工具poedit:

http://www.poedit.net/download.php#win32

MySQL中英混合首字母排序归类

在我前些日子写的音乐网站上,有9571个单独的歌手信息页面。列表位于:

http://www.fachun.net/musician/

为方便用户筛选歌手,我需要添加过滤器。

可以采用一种比较常见的过滤器,即根据首字母、或者中文的拼音首字母来筛选。

但需要考虑:

1. 中文的拼音如何获取

2. 其他语言的字符如何处理

 

在我的数据库中,这个表叫musician_ordered,character set统一为utf8,collation统一为utf8_general_ci。

为了让数据自身根据name字段预排序,我选择了(name, id)这个复合主键。

但还有个问题,数据是以utf8_general_ci进行的整理,而不是根据gbk排序,

英文和中文可能会混排在一起。

 

最简单的排序方法

最简单的排序方法只需要一条 SQL语句:

select * from musician_ordered order by convert(name using gbk) collate gbk_chinese_ci;

首先,对name字段进行gbk编码,然后,对编码后的内容根据gbk_chinese_ci进行整理排序。

这样得到的结果,英文是排在中文前面的,而且是根据拼音排序的。

 

使用Python脚本转换拼音

我选择了添加额外的一列pinyin来保存歌手名的拼音。 继续阅读MySQL中英混合首字母排序归类

Ubuntu简单配置SVN,完成自动部署

前几天在写web脚本,自己不擅长前端开发,所以联系了  小连,让他来负责页面的布局、调色。

之前我一个人的时候,是通过sftp上传文件,ssh管理MySQL和Apache。

但现在两个人,有可能会同时修改html、css、js,需要进行简单的版本控制。

下面简单记录设置SVN和部署的操作:

1. 安装

apt-get install subversion libapache2-svn

我的服务器上Apache老早就安装过了。如果你的服务器上还没有安装,可以执行:

apt-get install apache2

完成安装之后,Apache的mod_dav_svn默认就是已经启用的了。

2. 创建代码仓库文件夹

这里我把代码集中放在了/var/svn/,先创建这个文件夹:

cd /var/

mkdir svn

3. 修改dav_svn模块配置文件 继续阅读Ubuntu简单配置SVN,完成自动部署

MySQL优化再续:依靠子查询充分利用索引

前面一篇日志中,我记录了自己优化关联表的过程,当时提到一点: 把数据按取出的需要进行物理聚集

本篇我想强调的另一个的问题是:

任何一个查询,都必须充分利用索引。没有可利用的索引就建索引。

筛选条件太多,要考虑拆分成子查询来利用索引。

开始之前,我再次罗列几个表:

Album表: 专辑数据, 98万条记录,包含一个叫rate的字段

Tag表:    标签数据,20万条记录

Album_tags表:   关联表,300万条记录,保存了每个专辑都关联了哪些标签

我的需求是:

从Album表中取出和某个Tag关联的所有专辑,按照rate字段排序,再取rate最高的top 1000。

在上一篇日志里,我已经完成了取专辑ID的工作。

现在可以直接拿查询结果去和Album做inner join了。

但是Album表的大小超过1GB,这个inner join也不是可以随便写的。

 

1. 创建根据rate预排序的专辑表Tag_Albums

如果不预先排好序,而让MySQL每次都对得到的临时表做内存排序,将浪费不少时间。

我们首先来省掉这些时间,将Album中的数据按照rate降序导出到一个新的表:

create table Tag_Albums select rate,id,vote_count,album_name, pub_date from Album order by rate DESC;

这里我并不需要导出所有的列,需要哪些列就选择哪几列。

经过上面的精简,我得到的tag_albums表同样是98万条记录,却只有66MB。

2.  为Tag_Albums表增加主键和索引

建立这个表,是要让它预先按照rate排好序,所以选择主键是很关键的。

这里我选择复合的(rate, id)作为主键:

alter table tag_albums add primary key (`rate`,`id`)

如果错误地选择id作为主键,那我们导出的数据最后又是按照id排序和聚集了。

另外,我们还需要对id字段增加一个索引,至于何时用到,看了后文就知道了:

alter table tag_albums add key idx_id(id)

3. 预览最终的SQL

select T0.rate, T0.id, T0.album_name from tag_albums T0 inner join 
  (select T3.rate,T3.id from 
  (select album_id from album_tags T1 where tag_id = 8) T2, 
    tag_albums T3 where T3.id = T2.album_id order by T3.rate DESC,T3.id DESC limit 1000) T4 
on T0.rate = T4.rate and T0.id = T4.id
查询1

上面是我最终使用的版本,下面解释为什么需要这么写。

继续阅读MySQL优化再续:依靠子查询充分利用索引

在django1.5中使用django debug toolbar分析SQL性能

为了分析WEB页面中SQL执行的性能,我试着用了一下django debug toolbar,感觉很方便。

简述一下在django 1.5中安装和使用的步骤:

1.  下载解压后,直接setup.py install

2. 完成之后到project文件夹下编辑settings.py文件: 继续阅读在django1.5中使用django debug toolbar分析SQL性能

(后续)记录一次MySQL关联表的优化

昨天写了篇日志,记录自己尝试去优化一个MySQL表。

最后因为对结果不满意,用了一种非常“高富帅”的方法解决问题,即把整个表都放到内存中提升查询性能。

现在回忆起来,性能问题确实是因为自己滥用MySQL造成的。

 

首先,再描述一下场景。

需要优化的是一个关联表,名为 album_tags ,300万条记录,只有3个字段:

id

album_id    外键关联到专辑的id, integer

tag_id           外键关联到标签的id, integer

应用中需要获取和某个tag关联的所有专辑,平均情形有几千个。

通过inner join两个表来取数据: album_tags 和album。

当时发现这个查询比较费时,有时多达四五秒。

排查从子查询开始,测试了类似语句:

select album_id from album_tags where tag_id = 8

当结果集数量较多时,这条语句会变慢,比如取出2万条的结果,可能就需要两三秒。

我尝试explain这个select查询,发现是有使用索引的。

实际上,最初为了提升查询性能,我还特别在tag_id这一列上建了个hash索引。

 

1. HASH(tag_id)分区优化

了解到索引没问题,我产生了第一个思路:分表, 继续阅读(后续)记录一次MySQL关联表的优化