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