如今數(shù)據(jù)庫對于這個時代的我們來說,并不陌生了吧。最近,一個新的數(shù)據(jù)庫項目顯示,經(jīng)過身份驗證的用戶屬于特定租戶,應(yīng)僅允許其從自己的數(shù)據(jù)庫中提取數(shù)據(jù)。本文是實現(xiàn)數(shù)據(jù)庫多租戶這一目標的方法。本文將選擇了以提供簡單測試代碼為起點的策略,并使它逐層工作。它提供了具有測試,遷移和特定于租戶的小功能的完整解決方案。
1.每個故事都始于測試:PostsTest
讓測試驅(qū)動我的代碼成為了我的激情。多租戶不應(yīng)有所不同。首先,我們確定我們希望測試的外觀,然后使代碼發(fā)生。
這是一個非常簡單且公平的測試。為了使其工作,首要要求是TenantTestCase設(shè)置租戶。但是在深入探討之前,讓我們快速編寫我們的create助手。
2.TenantTestCase
通過測試,我們可以預(yù)期TenantTestCase該類將負責創(chuàng)建一個新公司,一個新用戶并對該用戶進行身份驗證。還應(yīng)設(shè)置特定于數(shù)據(jù)庫的連接。
通過使用RefreshDatabase,應(yīng)該自動遷移主數(shù)據(jù)庫。調(diào)用actingAs將建立身份驗證。至于用戶工廠,由于用戶屬于公司,因此應(yīng)遞歸解決該依賴關(guān)系。
3.工廠
該UserFactory會負責為我們創(chuàng)建新用戶。Laravel的默認UserFactory幾乎足夠好,我們只需要向其中添加company_id字段即可。
一旦需要創(chuàng)建新用戶,Laravel將嘗試解析CompanyFactory。讓我們接下來寫。
這CompanyFactory是一家新公司通過我們的測試而生的時刻,因此我決定利用它來按期望的那樣自動設(shè)置承租人數(shù)據(jù)庫連接PostsTest。
最后一個工廠是PostFactory。出于組織目的,我決定將所有主要工廠遷入database/factories/main并為的租戶工廠騰出空間database/factories/tenant。PostFactory非常簡單。
4. tenant_connect()和tenant_migrate()幫助器
顧名思義,tenant_connect()它將與租戶數(shù)據(jù)庫建立數(shù)據(jù)庫連接。由于這是測試階段,因此我們應(yīng)確保租戶數(shù)據(jù)庫接收到它自己的遷移,例如posts表。
該文件可以放在下database/helpers.php。不要忘記將其添加到作曲家自動加載中。
“ autoload”:{
“ classmap”:[
“數(shù)據(jù)庫/種子”,
“數(shù)據(jù)庫/工廠”
],
“文件”:[
“ database / helpers.php”
],
“ psr .4”:{
“ App \”: “ app /”
}
}
這將我們帶入下一個主題:遷移。
5.主要遷移
默認的database / migrations文件夾將保存主要連接的數(shù)據(jù)庫結(jié)構(gòu)。我們需要創(chuàng)建“ 公司”遷移并調(diào)整“ 用戶”以適應(yīng)某個company_id字段。
使用名稱手動創(chuàng)建公司遷移2014_10_12_000000_create_companies_table.php會將其放置在users遷移之前,這將防止任何外鍵沖突,因為要創(chuàng)建用戶表的公司表應(yīng)該已經(jīng)存在。
6.租戶遷移
在第(3)項中,我們建立了一種tenant_migrate()方法,該方法將使用文件夾database/migrations_tenant作為承租人數(shù)據(jù)庫結(jié)構(gòu)的源。讓我們create_posts_table在那里創(chuàng)建遷移。
至此,所有必要的遷移就結(jié)束了。接下來,我們需要處理應(yīng)用程序數(shù)據(jù)庫設(shè)置和模型的連接。
7.應(yīng)用程序數(shù)據(jù)庫設(shè)置
對于數(shù)據(jù)庫連接,讓我們重用上一篇文章中應(yīng)用的相同策略:a main和tenant數(shù)據(jù)庫。特別注意指向的新默認連接main。另一個有趣的地方是DB_DRIVER變量,它將允許我們在測試和實時應(yīng)用程序之間在SQLite和MySQL之間進行切換。
因為我們在談?wù)摂?shù)據(jù)庫設(shè)置,所以讓我們花點時間設(shè)置phpunit.xml文件。該文件應(yīng)包含這些變量
<env name =“ DB_DRIVER” value =“ sqlite” />
<env name =“ DB_CONNECTION” value =“ main” />
<env name =“ DB_DATABASE” value =“:內(nèi)存:” />
8.模型
還需要在租戶模型和主要模型之間劃分模型。讓我們在名稱空間下創(chuàng)建MainModel和TenantModelApp/Models。
主連接上的表應(yīng)該擴展MainModel,而“ Posts”表是特定于客戶的數(shù)據(jù)庫結(jié)構(gòu)的一部分,并且應(yīng)該擴展TenantModel。就個人而言,我分別使用命名空間AppModelsMain和AppModelsTenant。
9.路線
由于本文的重點是談?wù)撟馄冢晕覀儾灰速M時間談?wù)撀酚伞y試現(xiàn)在應(yīng)該通過。
10.總結(jié)
我們從創(chuàng)建帖子的測試開始,然后點擊一個端點以查看是否返回。但是在執(zhí)行測試之前,將調(diào)用setUpon方法TenantTestCase。
租戶測試用例類將創(chuàng)建一個用戶,該用戶屬于公司。在創(chuàng)建該公司的過程中,將建立一個新的數(shù)據(jù)庫連接,并通過tenant_migrate()助手進行遷移。完成所有這些操作后,“承租人測試用例”類將擁有一個經(jīng)過身份驗證的用戶。
一旦/posts端點被調(diào)用,已創(chuàng)建了一個用戶數(shù)據(jù)庫和已建立連接。通過使用Post具有默認連接的模型,該模型tenant將自動從連接的數(shù)據(jù)庫中獲取記錄。
所有這些使我們成功實施了測試。但是實際應(yīng)用呢?
11.租戶中間件
測試為綠色,但實際的應(yīng)用程序無法正常工作。這樣做的原因是因為測試正在建立租戶連接,但應(yīng)用程序卻沒有。我們可以通過實現(xiàn)租戶中間件來解決這個問題。
上述就是關(guān)于數(shù)據(jù)庫多租戶最終指南的全部內(nèi)容,想了解更多關(guān)于數(shù)據(jù)庫的信息,請繼續(xù)關(guān)注中培偉業(yè)。