产品的定位

做产品的都知道,是否支持多语言直接影响到产品的定位问题。

如果一个产品周期是一年的话,要完美支持多语言最少也得在加3个月!所需时间和页面数量、数据库表的数量和表的数据量成正比。

可以看出代价有多大,我们程序员就得和老板唠叨,做不得,成本太高。

如果前期不做,等到了后期项目表结构等都要重构,如果使用了大量的视图对于多语言来说就是恶梦。

非数据库方面的解决方案

请看我上一篇贴子 http://www.cnblogs.com/sunkaixuan/p/5699744.html

数据库表的设计

对于多语言来说最重要的就是清单表的设计, 就拿简历来说吧,至少会用到十几张清单表 (当然你也可以存储在一张表里用分类)

学历表:小学、中学、大学、博士 等等

工作年限表:习实生,1年工作经验,2年工作经验等等

...

多语言架构清单表的设计误区

如下图这种设计是存在严重缺陷的,列来存语言难道我多一种语言就要加一列,显然是不合理的

错误方案

正确的设计方案

名称                      清单ID     语言ID

Primary education   1            1

小学                       1            2

middle school         2            1

初中                       2            2

数据结构应该是这样的至少,相同的东西是一样的ID,名称不一样而已,产品架构千万不要用列存储。

这种表架构又会出一个问题

当使用语言ID来作为筛选时,就会遇到一个很大的问题,没错那就是视图的JOIN问题,如果我在视图里面写

人员表 JOIN 学历表  ON   学历表.ID=人员表.学历ID  AND  学历表.语言ID=几

没法写了对不,如果我在视图里写了1那就意味着我查出来的清单都只会是一种语言(语言ID为1的那个语言)

视图的作用

视图相当于虚拟表,可以方便的复用,视图还可以套视图,并且视图在索引合理的情况下,比单表查询还要快。 (索引覆盖就是一个很好的例子)

那怎么办呢?SqlSugar ORM已经为我们做好这一切

随着ORM性能瓶颈的提升,都玩会了EMIT 缓存这套,甚至拉姆达TO SQL都有开源项目 大大降低了ORM的门槛,SqlSugar也是拉姆达解析加EMIT玩的最早的ORM之一。

SqlSugar是为通用框架搭建而生,拥有了一定量的使用者,在6600万高并发的测试中也得到了使用者的好评。

虽然也有很多朋友抱怨问题,大致会有两个问题 实体转换报错,其实是字段类型不配引起的或者更改了表结构没有把.NET实例重启因为有缓存的原因。

我不能保证我的代码写的多优雅,但能保证我写的代码都能看懂。我宁可写IF ELSE也不会写让我脑子在转一圈的代码,我不会因为我一天能解决的问题去套一个使我花2天以上解决问题的设计模式,合理封装便可,没有过度设计。

SqlSugar在很多细节上都做过处理,比如线程安全、事务隔离等参数

使用SqlSugar ORM解决视图问题

1、我们就把视图语言ID设为1 (1为默认语言)
人员表 JOIN 学历表  ON   学历表.ID=人员表.学历ID  AND  学历表.语言ID=1 2、我们可以使用 LanguageHelper.UpdateView(db.Language, db); 帮我们生成其它语言的视图,只要使用在Application_Start执行一次便可以,当视图发生变化也需要在调一次或者重启程序

只要视图源码中包含LanguageId=1的所有视图都会创建出新的视图并且把LanguageId=1替换成你想要的ID

3、他会根据参数生成一个新的视图 原视图名_$_EN  ,新的视图和原视图一样只是名称和语言的值发生了变化
人员表 JOIN 学历表  ON   学历表.ID=人员表.学历ID  AND  学历表.语言ID=
4、var list=db.Qureyable<原视图名>().ToList()
ORM会自动识别新的视图进行查询,生成的SQL如下 SELECT * FROM 新视图名

下面是具体代码: 
  using (SqlSugarClient db = SugarDao.GetInstance())//开启数据库连接
{
db.Language = new PubModel.Language()
{
LanguageValue=,//多语言的值一般从COOKIES或SESSION取
Suffix="en"//多语言后缀同上
};
//给上面赋值后下面的程就可以使用了
int lanId=db.Language.LanguageValue;
var list = db.Queryable<LanguageTest>().Where(it => it.LanguageId == lanId).ToList(); /****************************多语言视图才是最大的问题***********************************/ //注意视图里里怎么办呢?视图里面的JOIN用到语言表怎么处理呢
//我们就写一个简单的视图作为例子,代码如下
/*create view V_LanguageTest
as
select * from LanguageTest where LanguageId=1
*/ //下面这代码写到 application_start 不需要重复执行
LanguageHelper.UpdateView(db.Language, db);
//执行完上面的代码会创建把所有带LanguageId=1的视图全部生成其它语言的视图
//现在数据库就有了 V_LanguageTest_$_en // V_LanguageTest_$_en结构如下
/*create view V_LanguageTest_$_en
as
select * from LanguageTest where LanguageId=2
*/ //V_LanguageTest__$_en 是我SqlSugar自动帮你创建的 当视图发生变化需要重新执行 LanguageHelper.UpdateView(db.Language, db); var list2=db.Queryable<V_LanguageTest>().ToList();
//生成的Sql等于 select * from V_LanguageTest_$_en db.Language.LanguageValue = ;//我们在把LanguageValue改成1
db.Language.Suffix = null;//后缀清空
var list3 = db.Queryable<V_LanguageTest>().ToList(); //生成的Sql等于 select * from V_LanguageTest //注意当 Suffix为null时使用的原始视图 //自定义视图替换规则请看下面两个参数
//db.Language.ReplaceViewStringKey 默认值为LanguageId=1
//db.Language.ReplaceViewStringValue 默认值为LanguageId = {0} }

SqlSugar学习下载地址:

http://www.cnblogs.com/sunkaixuan/p/5654695.html

多语言架构下如何正确的使用SQL视图的更多相关文章

  1. OpenGL Insights 阅读有感 - Tile Based架构下的性能调校 翻译

    Performance Tunning for Tile-Based Architecture Tile-Based架构下的性能调校 by Bruce Merry GameKnife译 译序 在大概1 ...

  2. MVC项目实践,在三层架构下实现SportsStore-09,ASP.NET MVC调用ASP.NET Web API的查询服务

    ASP.NET Web API和WCF都体现了REST软件架构风格.在REST中,把一切数据视为资源,所以也是一种面向资源的架构风格.所有的资源都可以通过URI来唯一标识,通过对资源的HTTP操作(G ...

  3. Rest架构下的增删改查

    首先还是要连接一下什么是Rest, REST是英文representational state transfer(表象性状态转变)或者表述性状态转移;Rest是web服务的一种架构风格;使用HTTP, ...

  4. Re:从 0 开始的微服务架构--(四)如何保障微服务架构下的数据一致性--转

    原文地址:http://mp.weixin.qq.com/s/eXvoJew3bjFKzLLJpS0Otg 随着微服务架构的推广,越来越多的公司采用微服务架构来构建自己的业务平台.就像前边的文章说的, ...

  5. asp.net core系列 62 CQRS架构下Equinox开源项目分析

    一.DDD分层架构介绍 本篇分析CQRS架构下的Equinox开源项目.该项目在github上star占有2.4k.便决定分析Equinox项目来学习下CQRS架构.再讲CQRS架构时,先简述下DDD ...

  6. x64架构下Linux系统函数调用

    原文链接:https://blog.fanscore.cn/p/27/ 一. 函数调用相关指令 关于栈可以看下我之前的这篇文章x86 CPU与IA-32架构 在开始函数调用约定之前我们需要先了解一下几 ...

  7. Arm64架构下静态编译Nginx

    这段时间,我一直忙于将 Rainbond 源码构建模块移植到 Arm64/aarch64 架构中.这一源码构建模块可以将指定代码仓库中包含的源码,拉取构建成为容器镜像,在各种容器平台中运行.目前支持的 ...

  8. Arm64架构下编译便携Python

    这段时间,我一直忙于将 Rainbond 源码构建模块移植到 Arm64/aarch64 架构中.对于 Python 项目而言,可以直接通过源代码编译成为可运行在各种容器平台之上的容器镜像.这个过程不 ...

  9. 100行代码实现一个RISC-V架构下的多线程管理框架

    1. 摘要 本文将基于RISC-V架构和qemu仿真器实现一个简单的多线程调度和管理框架, 旨在通过简单的代码阐明如何实现线程的上下文保存和切换, 线程的调度并非本文的重点, 故线程调度模块只是简单地 ...

随机推荐

  1. Xamarin.Android绑定库分享

    使用Xamarin.Android时,会用到各种第三方库,而这些库基本上是java编写的,要在Xamarin.Android中使用这些库,就需要通过Android Binding Project绑定对 ...

  2. 算法:poj1066 宝藏猎人问题。

    package practice; import java.util.Scanner; public class TreasureHunt { public static void main(Stri ...

  3. [php入门] 5、初学CSS从中记下的一些基础点(For小白)

    CSS是层叠式样式表,主要用来控制页面的样式. 一.CSS概述 应用CSS: 1.外部样式表,CSS写在一个单独的.CSS文件中,在head里加<link rel="styleshee ...

  4. [每日电路图] 1、基于AT89C52单片机最小系统接口电路【转】

              come from:http://www.21ic.com/dianlu/basis/interface/2015-04-21/621607.htm AT89C52是美国Atmel ...

  5. EF架构~二级域名中共享Session

    回到目录 对于一个有点规模的网站,都会有各个子网站,说是子网站,其实也都是独立的站点,一般通过二次域名来分开,如www.zzl.com,它可以有很多子网站,如image.zzl.com,file.zz ...

  6. Java程序员的日常—— 基于类的策略模式、List<?>与List、泛型编译警告、同比和环比

    早晨起得太早,昨晚睡得太晚,一天都迷迷糊糊的.中午虽然睡了半个小时,可是依然没有缓过来.整个下午都在混沌中....不过今天下载了一款手游--<剑侠情缘>,感觉不错,喜欢这种类型的游戏. 今 ...

  7. JQuery向导插件Step——第一个阉割版插件

    如果使用过JQuery Steps的朋友一定会发现这个插件有一个缺点,就是页面在第一次进入的时候,会进行一次很明显的DOM重绘--页面会闪一下. 尤其是前端代码比较庞大的时候,效果更为明显. 为了解决 ...

  8. rabbitmq消息队列——"路由"

    在之前的教程中,我们创建了一个简单的日志系统.我们能够向许多交换器转发日志消息. 在本教程中,我们将添加一个功能--我们让它仅仅接收我们感兴趣的日志类别.举例:我们 实现仅将严重级别的错误日志写入磁盘 ...

  9. ajax获取json对象

    ajax获取json对象 ajax获取json数据,都是一个原理,设置response 的Content-Type:application/json,这样浏览器自动会解析为json对象 $result ...

  10. java异常处理:建立exception包,建立Bank类,类中有变量double balance表示存款,Bank类的构造方法能增加存款,Bank类中有取款的发方法withDrawal(double dAmount),当取款的数额大于存款时,抛出InsufficientFundsException,取款数额为负数,抛出NagativeFundsException,如new Bank(100),

    建立exception包,建立Bank类,类中有变量double  balance表示存款,Bank类的构造方法能增加存款,Bank类中有取款的发方法withDrawal(double dAmount ...