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
