数据库的国际化问题

参照了Yii文档中的国际化部分,有点理解。

但是,个人认为,Web应用的国际化问题仍然没有彻底的解决。

Yii提供了语种的翻译支持,但是这仅仅只能满足小部分的业务需求。

当然,Yii也提供了CDbMessageSource作为数据库方面的翻译。

但是这跟CPhpMessageSource没什么区别,只是把翻译好的数据放入数据库了。

我的问题是这样的,比如产品类别信息的国际化。

我可以建立两张表,一张中文,一张英文。

或者只建立一张表,添加语种字段,标识语种。

问题来了:

当zh_cn的浏览器打开我的网页时,显示的商品类别必然是中文的。

当en_us的浏览器打开我的页面时,显示的商品类别必然是英文的。

那么,我如何自动的选择数据表,并读取这些数据呢?

现在做web开发的越来越依赖于数据库了,恨不得把所有东西都向数据库中放。

当然,上面的问题解决并不难,我只要判断用户的语言首选项,

然后动态的选择表,然后读取数据,也可以,照样可以解决问题。

问题的严重性在于,我的数据库是很庞大的。

我必须要根据语种去建立N张重复的表吗?那还不如直接按语种新建数据库呢。

或者不厌其烦的为每个表都增加语种字段?

相信上面的两种方案在实际开发中定是头疼的问题。

根据语种选择相应的数据库表也许改写Yii框架并不是很难,

但是如果我想要动态的指定数据库表呢,

比如我是zh_cn,但是我就想往en_us的表中写英文。

怎么办呢?

大家晓得,Yii支持数据库就两个,一个是DAO,一个就是AR

不用了,DAO灵活性很强大,完全可以根据上面的业务要求实现,但是太繁琐了。

AR用的就让人还有点意思,但是AR类的设计让人有点摸不到头脑,因为AR类针对性太强,伸缩性就差了点。

做过国际话的朋友可以交流一下,在下不甚感激!

讨教中。。。。。。

补充说明:

我说的可能有点迷茫,有点乱。

在上面的国际化问题中,我根本没有涉及到一点翻译的问题。

意思就是说我并不赞成使用Yii::t()这样的方法去资源文件中读取翻译好的文件。

为什么,举个最简单的例子,就是我的页面字符串长度的显示问题。

谁知道我的中文翻译成某个国家语言后的长度是多大,倒是页面偏了,或者换行了。

我可不想看到那样的结果。

我更倾向于使用CApplication::findLocalizedFile()去找翻译好的整个页面。

这样我们可以针对每个语种设计合适的页面,然后显示问题一点没有问题。

但是,我更更倾向于使用Theme,主题在我的工程里面多了一个角色,那就是语种。

不用多说,相信大家都知道。

然后说说我数据库的问题。

目前我们数据库倾向于根据语种设计多个数据库。

zh_cn和en_us两个数据库,当然还有其他语种的。

每个数据库的数据表结构完全一样。

唯一不同的就是每个语种数据库存放属于自己语言的数据信息。

现在我可以使用DAO去动态选择或者参数指定特定语种的数据库连接

来完成数据库的所有操作。

因为数据库表结构一样,所以我只关心数据库连接,而不担心CURD的操作。

问题在于AR类我就无奈了,有点不知所措了。

当然动态改变AR类的数据库连接,也没有问题,改改源代码就完成了。

关键在于没有办法参数指定AR类的数据库连接,当然也可以更改,

但是也学就把AR类改的面目全非了。

我在想,是否我们国际化的设计初衷就是错误的呢?

希望能得到有经验人士的帮助,给点建议也可以啊!

先谢谢了!

新的解决方案:使用表前缀区分语种!

例如数据库存在两个表:

cn_customer

en_customer

两张表的结构完全一样,就是表名的前缀不同,这是针对国际化问题设置的。

因为这两张表的结构相同,所以它可以使用同一个AR类去操作,只是操作的表前缀不同,

若前缀是’cn’,则对cn_customer表进行CURD操作。

数据库配置:

‘db’=>array(

'connectionString' => 'mysql:host=localhost;dbname=test',


'emulatePrepare' => true,


'username' => 'root',


'password' => '123456',


'charset' => 'utf8',


'tablePrefix'=>'cn_',

),

我默认的表前缀是’cn_’,注意一定要有下滑杠。

怎么动态指定表前缀,实时的对两张表操作呢?很简单,我只需要修改’db’组件的’tablePrefix’属性即可,感谢强这里将’tablePrefix’设置成可写属性。代码如下:

$db = Yii::app()->db;

$db->tablePrefix = ‘en_’;

//$customer = Customer::model()->findByPk(1);

//$this->render(‘index’,array(‘customer’=>$customer));

$customer = new Customer;

$customer->name = ‘zhognwen’;

$customer->save();

这种情况下,我们AR类使用起来就不受干扰的多了!

你这是 一个国家一个应用吗?那你一个国家用一套theme 应该可以解决问题吧?只需要 修改数据库和theme的名字。

谢谢你的回复!

不是的,我就一个应用啊,但是要适应多语言的情况。

使用theme可以解决界面语种的问题,但是不能解决数据库的问题啊。

如果是中文的页面就应该读取中文的数据,

英文的界面应该读取英文的数据。

问题是我不晓得数据库怎么设计。

目前的最新设计是一个数据库。

没个表前面加语种前缀。

比如product表吧,就有三个:

cn_product

en_product

fr_product

每次进行数据库CURD操作的时候,

都需要修改db的表前缀属性。

就是这样!

长点见识了

不错,我也是这样想的。我用theme 来做,然后用数据表前缀来区别