国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

SaaS多租戶架構數據源動態切換解決方案

開發 架構
在實際應用中,數據同步操作可能涉及到復雜的數據映射和處理邏輯,需要根據具體的業務需求進行設計和實現。同時,為了保障系統的穩定性和性能,可能還需要考慮引入事務管理、批量處理和異步處理等機制。

概述

隨著云計算和SaaS(Software as a Service)模型的興起,多租戶系統成為了構建靈活、高效應用的重要架構。在構建多租戶SaaS平臺時,數據庫方案的選擇直接關系到數據隔離、性能和可擴展性。

在SaaS平臺項目中,根據前端不同的域名查詢不同的數據庫,通常涉及到多租戶架構的實現。在這種架構中,一個應用實例可以服務多個客戶(租戶)【數據庫】,每個租戶的數據需要隔離存儲。實現這一目標的關鍵技術之一就是動態切換數據庫連接。

設計多租戶數據模型

在數據庫設計階段,你需要決定數據隔離的級別。通常有以下幾種隔離級別:

  • 獨立數據庫:每個租戶擁有一個獨立的數據庫實例。
  • 共享數據庫,獨立Schema:所有租戶共享同一個數據庫,但每個租戶有獨立的Schema。
  • 共享數據庫,共享Schema,共享數據表:所有租戶共享數據庫、Schema和數據表,但通過租戶ID字段進行數據隔離。

共享數據庫,獨立Schema

"共享數據庫,獨立Schema" 是一種在SaaS平臺中實現多租戶架構的策略,它在數據庫層面上提供了一種折中的數據隔離方法。

Oracle數據庫:在Oracle中一個數據庫可以具有多個用戶,那么一個用戶一般對應一個Schema,表都是建立在Schema中的,(可以簡單的理解:在Oracle中一個用戶一套數據庫表)

圖片圖片

在 MySQL 中,Schema 和 Database 可以認為是相同的概念。在 SQL 語句中,CREATE DATABASE 和 CREATE SCHEMA 基本上是等效的。所以,當你創建一個數據庫時,你也在事實上創建了一個模式。模式是一個邏輯上的容器,用于組織和管理數據庫對象,如表、視圖、存儲過程等。在 MySQL 中,模式和數據庫可以互換使用。

共享數據庫

在這種模式下,所有的租戶(即SaaS平臺的客戶)共享同一個物理數據庫服務器或數據庫實例。這意味著,盡管每個租戶都有自己的數據,但這些數據都存儲在同一個數據庫文件或數據庫集群中。這樣做的好處是可以減少硬件資源和維護成本,因為不需要為每個租戶單獨設置和維護數據庫實例。

獨立Schema

盡管數據庫是共享的,但每個租戶都有自己獨立的Schema。Schema是數據庫中的一種邏輯分組,它包含了一系列的數據庫對象,如表、視圖、索引、存儲過程等。在這個模式下,每個租戶的數據都存儲在自己的Schema中,這樣可以保證租戶之間的數據邏輯上是隔離的。

例如,假設有兩個租戶A和B,他們共享同一個數據庫"SaaSDB"。在"SaaSDB"中,可以分別為租戶A和租戶B創建兩個Schema(數據庫),分別是"SchemaA"和"SchemaB"。租戶A的所有數據都存儲在"SchemaA"中,而租戶B的數據存儲在"SchemaB"中。

優缺點

優點
  1. 資源利用率高:由于所有租戶共享同一個數據庫,硬件資源和數據庫維護成本較低。
  2. 易于管理:數據庫管理員只需要管理一個數據庫實例,簡化了維護和升級的工作。
  3. 隔離性:每個租戶的數據存儲在獨立的Schema中,邏輯上實現了數據隔離,減少了數據交叉污染的風險。
缺點
  1. 隔離性不如獨立數據庫:雖然Schema提供了一定程度的隔離,但如果Schema之間存在依賴關系或需要進行復雜的數據操作,隔離性可能不如完全獨立的數據庫。
  2. 性能問題:如果租戶數量增多,可能會導致數據庫性能問題,因為所有租戶都在競爭同一個數據庫資源。

總體來說,"共享數據庫,獨立Schema" 的模式在SaaS平臺中是一種常見的多租戶數據隔離策略,它在資源利用率和數據隔離性之間取得了平衡。開發者需要根據具體的業務需求和預期的租戶規模來決定是否采用這種模式。

SaaS多租戶架構數據庫設計

重點:在 SQL 語句中,CREATE DATABASE 和 CREATE SCHEMA 基本上是等效的。所以,當你創建一個SCHEMA時,就是在一個RDS實例下創建一個數據庫DATABASE。

圖片圖片

以newtrain.tinywan.com、hz_newtrain.tinywan.com、bj_newtrain.tinywan.com三個域名為例,每個域名對應一個租戶平臺站點,分別對應各自的數據源數據庫newtrain.tinywan.com、hangzhou.tinywan.com、beijing.tinywan.com。

實施方案

域名解析與路由

  • 在DNS系統中為每個域名配置A記錄,指向SaaS平臺的服務器
  • 在服務器上部署Web應用,并根據請求的Host頭部信息,確定租戶身份。

數據源配置

  • 在應用程序的配置文件中,定義每個租戶的數據源配置,包括數據庫URL、用戶名和密碼
  • 可以使用環境變量或配置中心來動態加載這些配置。

動態數據源切換

根據請求的域名或其他標識符,動態確定使用哪個數據庫連接。這通常通過中間件、攔截器或全局函數來實現。

示例:使用PHP實現域名路由中間件

<?php
/**
 * @desc 域名路由中間件
 * @author Tinywan(ShaoBo Wan)
 * @date 2024/11/20 18:14
 */
declare(strict_types=1);

namespace app\middleware;

use app\common\model\SaasModel;
use Webman\Http\Request;
use Webman\Http\Response;
use Webman\MiddlewareInterface;

class ConnectionMiddleware implements MiddlewareInterface
{
    /**
     * @param Request $request
     * @param callable $handler
     * @return Response
     */
    public function process(Request $request, callable $handler): Response
    {
        $domain = $request->header()['x-site-domain']?? 'https://newtrain.tinywan.com';
        $platform = SaasModel::where('domain', $domain)->field('id, domain, website')->findOrEmpty();
        if (!$platform->isEmpty()) {
            $request->website = $platform['website'];
        }
        return $handler($request);
    }
}

以上根據前端請求的域名標識符x-site-domain,動態確定使用哪個數據庫連接,通過中間件動態賦予全局請求對象$request->website,后續就可以使用。

項目應用

項目架構

項目使用超高性能可擴展PHP框架webman。webman是一款基于workerman開發的高性能HTTP服務框架。webman用于替代傳統的php-fpm架構,提供超高性能可擴展的HTTP服務。你可以用webman開發網站,也可以開發HTTP接口或者微服務。

數據庫連接使用ThinkORM。ThinkORM是一個基于PHP和PDO的數據庫中間層和ORM類庫,之前一直作為ThinkPHP5.*系列的內置ORM類,以優異的功能和突出的性能著稱,現已經支持獨立使用,并作了升級改進,提供了更優秀的性能和開發體驗,最新版本要求PHP7.1+。

數據庫連接中間

示例:域名路由中間件

<?php
/**
 * @desc 域名路由中間件
 * @author Tinywan(ShaoBo Wan)
 * @date 2024/11/20 18:14
 */
declare(strict_types=1);

namespace app\middleware;

use app\common\model\SaasModel;
use Webman\Http\Request;
use Webman\Http\Response;
use Webman\MiddlewareInterface;

class ConnectionMiddleware implements MiddlewareInterface
{
    /**
     * @param Request $request
     * @param callable $handler
     * @return Response
     */
    public function process(Request $request, callable $handler): Response
    {
        $domain = $request->header()['x-site-domain']?? 'https://newtrain.tinywan.com';
        $platform = SaasModel::where('domain', $domain)->field('id, domain, website')->findOrEmpty();
        if (!$platform->isEmpty()) {
            $request->website = $platform['website'];
        }
        return $handler($request);
    }
}

數據庫配置

ThinkORM配置文件:config/thinkorm.php

<?php
/**
 * @desc ThinkORM配置文件
 * @author Tinywan(ShaoBo Wan)
 * @date 2024/11/14 15:14
 */
declare(strict_types=1);

return [
    'default' => 'train',
    'connections' => [
        'train' => [
            'type' => 'mysql',
            'hostname' => '127.0.0.1',
            'database' => 'newtrain.tinywan.com',
            'username' => 'root',
            'password' => '123456'
        ],
        'hangzhou' => [
            'type' => 'mysql',
            'hostname' => '127.0.0.1',
            'database' => 'hangzhou.tinywan.com',
            'username' => 'root',
            'password' => '123456'
        ],
        'beijing' => [
            'type' => 'mysql',
            'hostname' => '127.0.0.1',
            'database' => 'beijing.tinywan.com',
            'username' => 'root',
            'password' => '123456'
        ]
    ],
];

Model模型使用

BaseModel.php 基礎模型

<?php
/**
 * @desc 基礎模型
 * @author Tinywan(ShaoBo Wan)
 * @date 2024/11/2 15:09
 */
declare(strict_types=1);

namespace app\common\model;

use think\Model;

class BaseModel extends Model
{
    /**
     * 設置當前模型的數據庫連接
     * @var string
     */
    protected $connection;

    /**
     * BaseModel constructor.
     * @param array $data
     */
    public function __construct(array $data = [])
    {
        $this->connection = \request()->website ?? 'train';
        parent::__construct($data);
    }
}

CityModel.php 公共模型,對應數據庫表名common_city。

<?php
/**
 * @desc 市模型
 * @author Tinywan(ShaoBo Wan)
 * @date 2024/12/13 14:59
 */
declare(strict_types=1);

namespace app\common\model;

use think\Model;

class CityModel extends Model
{
    /** 數據庫配置 */
    protected $connection = 'train';

    /** 設置當前模型對應的完整數據表名稱 */
    protected $table = 'common_city';
}

公共模型CityModel類里面定義了connection屬性,則該模型操作的時候會自動按照給定的數據庫配置進行連接,而不是配置文件中設置的默認連接信息.

業務 MeetingModel.php 會議模型類。對應數據庫表名resty_meeting

<?php
/**
 * @desc 會議模型類
 * @author Tinywan(ShaoBo Wan)
 * @date 2024/11/17 11:55
 */
declare(strict_types=1);

namespace app\common\model;

class MeetingModel extends BaseModel
{
    /** 設置當前模型對應的完整數據表名稱 */
    protected $table = 'resty_meeting';
}

業務控制器或者服務使用

<?php
/**
 * @desc 會議
 * @author Tinywan(ShaoBo Wan)
 * @date 2023/11/9 16:57
 */
declare(strict_types=1);

public function meetingList(\support\Request $request, int $organizationId) : \support\Response
{
    $meetingList = \app\common\model\MeetingModel::where([
        'organization_id' => $organizationId,
        'create_user_id' => $this->userId
    ])->select();
    return json($meetingList->toArray());
}

Db類使用

可以調用Db::connect方法動態配置數據庫連接信息

<?php
/**
 * @desc 會議
 * @author Tinywan(ShaoBo Wan)
 * @date 2023/11/9 16:57
 */
declare(strict_types=1);

public function datasetList(\support\Request $request) : \support\Response
{
    $res = \think\facade\Db::connect(\request()->website)
        ->table('resty_meeting')
        ->field('id,name')
        ->select();
    return json($res->toArray());
}

connect方法必須在查詢的最開始調用,而且必須緊跟著調用查詢方法,否則可能會導致部分查詢失效或者依然使用默認的數據庫連接。動態連接數據庫的connect方法僅對當次查詢有效。這種方式的動態連接和切換數據庫比較方便,經常用于多數據庫連接的應用需求。

動態連接到目標數據庫

在SaaS平臺中,如果需要根據前端傳遞的配置信息動態連接到目標數據庫并將數據拉取到本地數據庫,可以采用以下步驟實現

  • 前端傳遞配置信息。前端在用戶操作時,將目標數據庫的連接信息作為請求參數發送到后端。這些配置信息通常包括數據庫類型、主機地址、端口、數據庫名、用戶名和密碼等。
  • 驗證和解析配置信息。后端接收到配置信息后,首先進行驗證,確保其合法性和安全性。解析配置信息,并準備用于數據庫連接的參數。
  • 動態數據源管理。創建一個動態數據源管理器,它可以根據傳入的配置信息動態創建數據庫連接。
  • 數據同步。根據目標數據庫的連接信息,建立連接并執行數據查詢操作。然后將查詢結果同步到本地數據庫。這可能涉及到以下步驟:

建立連接:使用動態數據源管理器創建的目標數據庫連接。

執行查詢:在目標數據庫上執行SQL查詢,獲取所需數據。

映射數據:將查詢結果映射到本地數據庫的表結構中。

寫入本地數據庫:將映射后的數據插入到本地數據庫中。

  • 異常處理和日志記錄。在整個數據同步過程中,需要妥善處理可能出現的異常情況,并記錄相關操作日志,以便于問題追蹤和系統維護。
  • 安全性考慮
  • 加密敏感信息:確保所有的數據庫憑證信息在存儲和傳輸過程中都是加密的。
  • 權限控制:確保只有授權的用戶或服務才能訪問數據同步功能。
  • SQL注入防護:對動態執行的SQL進行嚴格的安全檢查,避免SQL注入攻擊。

自定義函數

函數配置文件app/functions.php新增函數dynamic_connect_db()

/**
 * @desc: 動態切換數據庫
 * @param string $name
 * @param array $connection
 * @return \think\db\ConnectionInterface
 * @author Tinywan(ShaoBo Wan)
 */
function dynamic_connect_db(string $name, array $connection): \think\db\ConnectionInterface
{
    try {
        $connect = \think\facade\Db::connect($name);
    } catch (\Throwable $e) {
        // 獲取配置參數
        $config  = \think\facade\Db::getConfig();

        // 配置具體的數據庫連接信息
        $config['connections'][$name] = $connection;

        // 初始化配置參數
        \think\facade\Db::setConfig($config);

        // 創建/切換數據庫連接查詢
        $connect = \think\facade\Db::connect($name);
    }
    return $connect;
}

動態使用

調用自定義函數dynamic_connect_db()方法動態數據庫連接查詢,這里查詢一個不存在的配置數據庫zhejiang 浙江站點。

/**
 * @desc: 動態切換數據庫
 * @param Request $request
 * @return Response
 * @throws DataNotFoundException
 * @throws DbException
 * @throws ModelNotFoundException
 * @author Tinywan(ShaoBo Wan)
 */
public function dynamicConnectDb(Request $request): Response
{
    $connection = [
        'type' => 'mysql',
        'hostname' => '127.0.0.1',
        'database' => 'zhejiang.tinywan.com',
        'username' => 'root',
        'password' => '123456'
    ];
    $connect = dynamic_connect_db('zhejiang', $connection);
    $result = $connect->table('resty_meeting')->where('id', 1)->find();
    var_dump($result);
    return json($result->toArray());
}

在實際應用中,數據同步操作可能涉及到復雜的數據映射和處理邏輯,需要根據具體的業務需求進行設計和實現。同時,為了保障系統的穩定性和性能,可能還需要考慮引入事務管理、批量處理和異步處理等機制。

責任編輯:武曉燕 來源: 開源技術小棧
相關推薦

2015-08-12 15:46:02

SaaS多租戶數據存儲

2023-11-29 08:35:28

群多租戶ES運維

2023-06-07 13:50:00

SaaS多租戶系統

2023-12-14 12:26:16

SaaS數據庫方案

2022-01-12 17:39:16

Spring多租戶數據

2020-09-15 07:00:00

SaaS架構架構

2025-11-26 01:25:00

數據源系統分庫分表

2025-01-09 14:39:40

2022-05-10 10:43:35

數據源動態切換Spring

2025-01-17 09:11:51

2025-12-12 07:35:19

SpringBoot業務系統數據庫

2018-12-03 12:07:54

南京新動態解決方案

2015-04-02 11:04:27

云應用SaaSOFBIZ

2009-09-22 11:56:58

ibmdwSaaS

2023-02-06 14:44:00

嚴選數據源DB

2016-12-28 18:08:11

RiverbedSaaS數字化轉型

2025-08-26 01:15:00

Spring項目數據源

2011-07-29 10:21:03

iPad 橫豎屏 切換

2022-09-13 07:14:29

云計算SaaS多租戶

2024-05-28 08:17:54

點贊
收藏

51CTO技術棧公眾號

欧洲日本亚洲国产区| 亚洲欧美综合v| 亚洲精品一品区二品区三品区| av久久网站| 精品国产成人在线| www国产免费| 亚洲精品韩国| 91精品国产色综合久久不卡98口 | 色婷婷久久一区二区| 天堂在线免费av| 国产成人小视频| 国产精品美女诱惑| 日韩一区二区三区精品| 日韩激情视频在线| 97电影在线看视频| 亚洲国产中文字幕在线视频综合| 国内精品在线观看视频| 老司机午夜精品视频在线观看| 国产狼人综合免费视频| 成人香蕉社区| 日韩中文视频免费在线观看| 77thz桃花论族在线观看| 91久久一区二区| av777777| 欧美国产97人人爽人人喊| 日韩精品在线中文字幕| 乱人伦精品视频在线观看| 91黄色国产视频| 99久久久久| 国产成人在线播放| 日韩深夜影院| 欧美高清激情视频| 99综合久久| 最近2019中文免费高清视频观看www99 | 久久免费在线观看| 91精品美女| 日韩精品一区二区视频| 91九色在线播放| 欧美精品一区二区高清在线观看| 国产在线1区| 欧美年轻男男videosbes| av电影在线播放高清免费观看| 色悠悠久久综合| h网站在线免费观看| 欧美在线免费播放| 免费在线观看av| 欧美一级高清大全免费观看| 日韩成人伦理| 日韩成人在线视频| 国产在线|日韩| www.亚洲男人天堂| 57pao成人永久免费| 久久精品国产91精品亚洲 | 国产一区激情| 国产欧美在线播放| 手机亚洲手机国产手机日韩| 91午夜理伦私人影院| 亚洲激情中文| 欧美日韩精品免费看 | 欧美综合国产精品久久丁香| 无码日韩精品一区二区免费| 国产精品久久久久久久天堂| 成人av网站观看| 激情欧美日韩| 九一成人免费视频| 不卡一区二区在线| 成年人视频免费在线播放| 一道本在线免费视频| 日韩欧美自拍偷拍| 午夜在线免费观看视频| 色琪琪一区二区三区亚洲区| 人人妻人人澡人人爽欧美一区双| 久久精品国语| 国产精品免费一区二区| 天堂资源在线中文精品| 久久成人人人人精品欧| 都市激情一区| 北条麻妃国产九九精品视频| 天天色综合社区| 一区二区在线视频播放| 99热在线精品观看| 成人av免费| 欧美国产高潮xxxx1819| 免费h精品视频在线播放| 亚洲免费av片| 国产精品88av| 久久的色偷偷| 免费在线看污| 日产精品高清视频免费| 欧美理论电影在线播放| 国产精品女人毛片| 久久人体视频| 欧美人xxx| 国产精品国产精品| 午夜精品久久久久久久久久| 亚洲网站三级| 成人免费观看视频在线观看| 精品国产一区二区三区忘忧草 | 丰满少妇在线观看| 高跟丝袜欧美一区| 粉嫩一区二区三区在线观看| 99视频在线播放| 欧美在线一区二区| 亚洲欧美福利一区二区| 夜夜嗨aⅴ免费视频| 亚洲在线中文字幕| av在线app| 日本精品一区二区三区在线| 国产一区欧美| 国产乱子伦农村叉叉叉| 国产日韩欧美视频在线| 在线观看欧美成人| 蜜桃av一区二区三区| 久久久久久77777| 成人在线小视频| 在线看日本不卡| 国产精品99视频| 亚洲无吗一区二区三区| 日韩欧美自拍偷拍| 日韩精品一区二区三区中文| 欧美激情精品久久久| 成人性生交大片免费看中文| 婷婷精品在线观看| 成人av免费电影网站| 羞羞视频在线观看| 免费在线激情视频| 韩国三级大全久久网站| 99国产精品白浆在线观看免费| 国产大片精品免费永久看nba| 欧美精品一区二区不卡| 亚洲天堂久久久久久久| 国产一区欧美一区| 极品少妇一区二区三区| 亚洲精品一区二区妖精| 蜜桃视频欧美| 女仆av观看一区| 成人欧美magnet| 欧美性猛交7777777| 亚洲精品无人区| 国产精品久久网| 日韩免费一区二区三区在线播放| 精彩视频一区二区三区| 精品入口麻豆88视频| 国产乱妇乱子| 日韩免费中文专区| 98国产高清一区| 欧美国产第二页| 一本色道久久综合亚洲aⅴ蜜桃 | 国产淫片免费看| 精品久久久久国产| 亚洲一区欧美激情| 四虎久久免费| 337p日本欧洲亚洲大胆色噜噜| 国产一区二区毛片| 在线91av| 亚洲高清在线观看一区| 在线播放日韩av| 蜜臀av性久久久久蜜臀av麻豆| 伊人网在线免费观看| 国产精品视频免费一区| 欧美日韩成人在线一区| a级日韩大片| 国产精品三级a三级三级午夜| 欧美日韩国产免费一区二区| 雨宫琴音一区二区在线| 国产三级在线观看| 亚洲精品国产suv一区88| 中文字幕最新精品| 国产精品久久久久久久浪潮网站| 香蕉久久精品| 亚洲精品久久久中文字幕| 欧美一区二区三区四区在线观看| 综合在线一区| 极品国产人妖chinesets亚洲人妖| 在线播放av更多| 亚洲一区二区久久久久久| 亚洲日本丝袜连裤袜办公室| 香蕉久久精品| 国产欧美高清在线| 成人高清视频观看www| 日韩av影视综合网| 91麻豆精品国产91久久久资源速度 | 日本a口亚洲| caoporn97在线视频| 伊人久久大香线蕉成人综合网| 精品一区二区三区av| jizzjizz少妇亚洲水多| 欧美黑人又粗又大又爽免费| 久久视频免费在线播放| 久久久久久久综合日本| 成人性生交大片免费看中文| 93在线视频精品免费观看| 亚洲女人天堂在线| 国产女人水真多18毛片18精品| 精品国产一区二区三区久久久狼 | 中文字幕亚洲激情| 91在线视频观看| 久久99久久99| 一区二区三区免费在线观看| 成人在线亚洲|