• 多语言架构下如何正确的使用SQL视图


    产品的定位

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

    如果一个产品周期是一年的话,要完美支持多语言最少也得在加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=2

    4、var list=db.Qureyable<原视图名>().ToList()
    ORM会自动识别新的视图进行查询,生成的SQL如下 SELECT * FROM 新视图名


    下面是具体代码:
      using (SqlSugarClient db = SugarDao.GetInstance())//开启数据库连接
                {
                    db.Language = new PubModel.Language()
                    {
                         LanguageValue=2,//多语言的值一般从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 = 1;//我们在把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

  • 相关阅读:
    FastJson序列化枚举类
    优雅计时StopWatch
    spark算子之aggregateByKey
    scala系列列表
    iOS开发证书不受信任
    .NET Core 中的鉴权授权正确方式
    设置双击直接打开.ipynb文件
    Ubuntu18添加开机启动项
    iOS ObjectC 笔记(二)GCD
    iOS VideoToolBox decoder解码失败(12909和12911)问题解决(二)
  • 原文地址:https://www.cnblogs.com/sunkaixuan/p/5709583.html
Copyright © 2020-2023  润新知