.NET SAAS 架構與設計 -SqlSugar ORM

1、數據庫設計

常用的Saas分庫分爲2種類型的庫 

1.1 基礎信息庫

主要存組織架構 、權限、字典、用戶等 公共信息 

性能優化:因爲基礎信息庫是共享的,所以我們可以使用 讀寫分離,或者二級緩存來進行性能上的優化

2.2 業務庫

我們要進行的分庫都基於業務庫進行分庫,例如 A集團使用 A01庫 ,B集團使用B01庫 ,也可以多個小集團使用一個 數據庫

如下:

 業務庫1   :集團A

 業務庫2  :    集團B, 集團F

 業務庫3 :     集團C, 集團D, 集團E

性能優先:因爲合理的進行了分庫,所以在性能上並沒有什麼瓶頸,並且數據庫可以扔到不同的服務器上

2、表設計

下面的表設計的比較簡單,主要是通過用戶可以拿到當前用戶的連接字符串,然後進行數據庫操作

2.1 數據庫配置表    

主鍵、數據庫連接信息、集團ID  (基礎信息庫)

2.2 用戶表  

主鍵、用戶名、密碼、集團ID (基礎信息庫)

 

3、代碼編寫

下面的代碼很簡單,我們通了多租戶方式實現了動態根據用戶獲取不同的業務庫

操作業務庫我們使用   DbManger.BizDb

操作基礎信息庫我們使用 DbManger.MasterDb

如果我們要用到事務就用  DbManger.Db 

 /// <summary>
    /// 數據庫管理
    /// </summary>
    public class DbManger
    {
 
       /// <summary>
       /// 獲取業務庫對象
       /// </summary>
        public static ISqlSugarClient BizDb 
        {
            get 
            {
                UserInfo user = GetUserInfo();//獲取用戶數據庫連接字符串信息
                var configId = user.OrgId.ToString();//集團ID(也可以叫租戶ID)
                if(!Db.IsAnyConnection(configId)){
                      Db.AddConnection(new ConnectionConfig() { 
                        ConfigId = configId, 
                        ConnectionString = "DataSource=" + user.Connection, 
                        DbType = DbType.SqlServer,
                         IsAutoCloseConnection = true });
                }      
                var result=Db.GetConnection(configId);
               //可以給業務庫result設置AOP
                return result;
            }
        }
 
 
        /// <summary>
        /// 基礎信息庫
        /// </summary>
        public static ISqlSugarClient MasterDb
        {
            get
            {
                //如果是跨服務庫分庫,也需要動態配置的,因爲庫的IP會變
                //參考業務庫用法
                return Db.GetConnection("default");
            }
        }
 
 
        /// <summary>
        /// 利用SqlSugarScope單例+多租戶來處理多庫事務
        /// </summary>
        public static SqlSugarScope Db =new SqlSugarScope(new ConnectionConfig()
        {
            ConfigId="default",
            DbType = SqlSugar.DbType.SqlServer,
            ConnectionString =  @"基礎信息庫連接字符串",
            IsAutoCloseConnection = true
        },
         db =>
         {
             //基礎庫AOP
             db.Aop.OnLogExecuting = (s, p) =>
             {
                            
             };
 
         });
 
        /// <summary>
        /// 獲取用戶數據庫連接字符串信息
        /// </summary>
        /// <returns></returns>
        private static UserInfo GetUserInfo()
        {
            throw new System.NotImplementedException();
        }
 
    }

使用用例,繼承後直接使用

 public class OrderManger: DbManger
    {
        public void Test() 
        {
            try
            {
                Db.BeginTran();//用Db管理 MasterDb和BizDb事務
 
 
                MasterDb.Insertable(xxx).ExecuteCommand();//操作基礎信息庫
                BizDb.Insertable(xxx).ExecuteCommand();//操作業務庫
 
 
                Db.CommitTran();//統一事務
    
             }
            catch (System.Exception ex)
            {
                Db.RollbackTran();
                throw ex;
            };
        }
    }

  

4、跨庫查詢

4.1 跨庫同服務器

跨庫查詢我們要用BizDb進行查詢,因爲BizDb是多變的,而MasterDb是固定的,查詢用BizDb爲主

    var List = BizDb.Queryable<Order>()
            .LeftJoin<Custom>((o, cus) => o.CustomId == cus.Id)
            .AS<Custom>("SQLSUGAR4XTEST.dbo.Custom") //主表用AS("") 從表用AS<T>("")
            .Where(o => o.Id == 1)
            .Select((o, cus) => new ViewOrder { Id = o.Id, CustomName = cus.Name })
            .ToList();

生成的SQL如下:

SELECT  [o].[Id] AS [Id] ,
        [cus].[Name] AS [CustomName]  
FROM [Order] o 
Left JOIN [SQLSUGAR4XTEST].[dbo].[Custom] cus --生成的Sql就多了庫名
ON ( [o].[CustomId] = [cus].[Id] )   WHERE ( [o].[Id] = @Id0 )

注意:上面的例子是SqlServer跨庫查詢的用法,不同的數據庫跨庫查詢用法不一樣

 更多用法: https://www.donet5.com/Home/Doc?typeId=2244

4.2跨庫不同服務器

因爲我們基礎信息庫是固定的,所以我們可以把基礎信息庫,同步到不同的服務器上,通過讀分離的方式 ,那麼每個業務服務器都會有一個

基礎信息庫了,然後在通過4.1的方式實現

 

5、業務表創建

我們可以通過CodeFirst創建業務庫和表

https://www.donet5.com/Home/Doc?typeId=1206

 

7、表過濾

一個業務庫中的表對應多個集團,那我們設計表的時候肯定有個 OrgId或者租戶ID進行數據表區別

我們需要將DbManger.bizDb進行修改,添加相應的表過濾器如果表中有OrgId的就可以添加過濾器

/// <summary>
/// 獲取業務庫對象
/// </summary>
public static ISqlSugarClient BizDb 
{
    get 
    {
         UserInfo user = GetUserInfo();//獲取用戶數據庫連接字符串信息
         var configId = user.OrgId.ToString();//集團ID(也可以叫租戶ID)
         if(!Db.IsAnyConnection(configId)){
               Db.AddConnection(new ConnectionConfig() { 
                        ConfigId = configId, 
                        ConnectionString = "DataSource=" + user.Connection, 
                        DbType = DbType.SqlServer,
                         IsAutoCloseConnection = true });
           } 
                 
          var result=Db.GetConnection(configId);
          result.QueryFilter.Add(new TableFilterItem<Order>(it => it.OrgId==configId);//添加表過濾器
         //可以多個表
          
         return result;
    }
}

https://www.donet5.com/Home/Doc?typeId=1205

8、高安全性日誌

我們可以通過差異日誌拿到數據更變記錄,記錄到日誌,SAAS操作一些核心數據差異日誌肯定少不了,安全係數高

db.Aop.OnDiffLogEvent = it =>
{
                //操作前記錄  包含: 字段描述 列名 值 表名 表描述
                var editBeforeData = it.BeforeData;
                //操作後記錄   包含: 字段描述 列名 值  表名 表描述
                var editAfterData = it.AfterData;
                var sql = it.Sql;
                var parameter = it.Parameters;
                var data = it.BusinessData;//這邊會顯示你傳進來的對象
                var time = it.Time;
                var  diffType=it.DiffType;//enum insert 、update and delete  
                   
                //Write logic
};
 
db.Insertable(new Student() { Name = "beforeName" })
.EnableDiffLogEvent() //注意需要加上啓用日誌,可以傳參數
.ExecuteReturnIdentity(); 

具體用法:https://www.donet5.com/Home/Doc?typeId=1204

 

9、總結

SAAS架構用到技術基本上都是現有功能,我這一篇文章相當於一個彙總,本人也做了6年SAAS架構,至少目前的方案是成熟方案 ,並且有產品驗證並且上線運營,如果有更好的建議可以回覆,或者直接找我溝通

源碼下載: https://github.com/donet5/sqlsugar

Nuget: 安裝SqlSugarCore

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章