原有系统拓展多语言建表问题

主要讨论模糊查查询

需求
比如我们有一个客户表,记录了客户Id、客户名称、客户地址、客户电话等,其中客户名称和客户地址是多语的,而且需要支持简体中文、繁体中文和英语
原有系统表

create table Client
(
 ClientId int primary key,
 Name nvarchar(50),
 Address nvarchar(50),
 TelephoneNumber varchar(50)
)

一、为每个多语字段建立对应语言的字段列。

于是我们可以将客户表拓展如下:

create table Client
(
 ClientId int primary key,
 Name nvarchar(50),
 NameCht nvarchar(50),
 NameEng varchar(200),
 Address nvarchar(50),
 AddressCht nvarchar(50),
 AddressEng varchar(200),
 TelephoneNumber varchar(50)
)

优点:查询方便

缺点:这种建表查询会使用到比较多的索引,并且后续新增语言的时候需要新增列

查询语句

select * from Client where name_lang like input%

二、建立统一的翻译表,在翻译表中使用单列存储多语言

create table Translation 
(
 TranslationId int primary key,
 TableId int(11),
 Table nvarchar(200),
 Column nvarchar(200),
 Lang nvarchar(200),
 Text nvarchar(200),
)

优点:不需要动原来的数据表,可以把翻译统一管理起来,后台做翻译设计的时候也比较方便,一张表即可,并且动态拓展翻译语言也比较方便

缺点:这种查询就比较麻烦了, 需要先模糊查询查出对应的id,再去对应的数据表中使用 in 查出对应的行,后台做展示的时候还涉及到合并,而且还不好做外键关联,在删除数据的时候需要增加delete语句

查询语句:

select * from Client where id in
(select id from Translation where Text like input% and Table ='Client'
and Column='name' and Lang='lang')

有没有更加合理的设计表,能解决外键关联动态增加新语种后台列表只做简单的查询的呢

本作品采用《CC 协议》,转载必须注明作者和本文链接
reading
白小二
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 1
sanders

还有一种数据分割方法,以你的客户表为例:

create table Client
(
 ClientId int primary key,
 Name nvarchar(50),
 Address nvarchar(50),
 TelephoneNumber varchar(50),
 lang varchar(10) # 增加语言列标注当前数据所采用的语言
)

这样我们需要再 lang 字段上做索引,以便在查询时能根据用户的语言环境通过模型全局作用域增加查询条件,如下:

class Client extends Model
{
    public function booted()
    {
        static::addGlobalScope('lang', fn(Builder $builder) => $builder->where('lang', config('app.locale'));
    }
}
1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!