考慮這個數據庫設計的多租戶業務線的Web應用程序:如何在沒有組合鍵的情況下執行二級關係?
一個Tenant
是網絡應用的租戶,一個Tenant
有許多Shops
和許多Customers
(Customer
記錄不Tenants
之間共享,所以它是有效的多個Customer
記錄指代相同的現實生活中的人),並且每個Shop
有許多Jobs
。 A Job
也與每個Customer
相關聯。
存在着似乎這樣的問題:有沒有需要一個簡單的約束求解,以防止其中Job
的CustomerId
變更爲Customer
不屬於母公司所Tenant
,從而產生無效數據的情況。
這是本模式:
CREATE TABLE Tenants (
TenantId bigint IDENTITY(1,1) PRIMARY KEY
...
)
CREATE TABLE Shops (
TenantId bigint FOREIGN KEY(Tenants.TenantId),
ShopId bigint IDENTITY(1,1) PRIMAREY KEY,
...
)
CREATE TABLE Customers (
TenantId bigint FOREIGN KEY(Tenants.TenantId),
CustomerId bigint IDENTITY(1,1) PRIMARY KEY
...
)
CREATE TABLE Jobs (
ShopId bigint FOREIGN KEY(Shops.ShopId)
JobId bigint IDENTITY(1,1) PRIMARY KEY,
CustomerId bigint FOREIGN KEY(Customers.CustomerId)
)
目前我能想到的唯一的解決辦法是改變設計中使用組合鍵始終包括父Tenant.TenantId
,然後將其相應的共享:
CREATE TABLE Shops (
TenantId bigint,
ShopId bigint IDENTITY(1,1),
...
PRIMARY KEY(TenantId, ShopId)
FOREIGN KEY(TenantId REFERENCES Tenants (TenantId))
)
CREATE TABLE Customers (
TenantId bigint,
CustomerId bigint IDENTITY(1,1)
...
PRIMARY KEY(TenantId, CustomerId)
FOREIGN KEY(TenantId REFERENCES Tenants (TenantId))
)
CREATE TABLE Jobs (
TenantId bigint
ShopId bigint
JobId bigint IDENTITY(1,1),
CustomerId bigint
PRIMARY KEY(TenantId, ShopId, JobId)
FOREIGN KEY(TenantId REFERENCES Tenants (TenantId))
FOREIGN KEY(TenantId, ShopId REFERENCES Shops(TenantId, ShopID))
FOREIGN KEY(TenantId, CustomerId REFERENCES Customers(TenantId, CustomerId))
)
......雖然看起來有點像黑客,但有很多冗餘數據 - 尤其是因爲無論如何都使用了IDENTITY
。有沒有什麼方法可以在數據發生變化時測試JOIN的一致性?
您使用的是什麼DBMS/SQL?功能和習語各不相同。 – philipxy
@philipxy MSSQL Server在大多數情況下,有時候是PostgreSQL和MySQL。 – Dai