Рассмотрим структуру базы данных для нескольких аренды линии прямой-бизнеса веб-приложением:Как я могу применять отношения второй степени без составных клавиш?
Tenant
является арендатором веб-приложения, Tenant
имеет много Shops
и много Customers
(Customer
записи не распределяются между Tenants
, поэтому он действителен для нескольких записей Customer
, чтобы обратиться к одному и тому же человеку в реальной жизни), и у каждого Shop
есть много Jobs
. A Job
также связан с каждым Customer
.
Там существует проблема в том, что там, кажется, не тривиальное ограничение решение, чтобы предотвратить случай, когда Job
«s 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
используется в любом случае. Есть ли способ, которым РСУБД может тестировать JOINs для согласованности всякий раз, когда данные мутируются?
Какие СУБД/SQL вы используете? Особенности и идиомы различаются. – philipxy
@philipxy MSSQL Server в большинстве случаев, иногда PostgreSQL и MySQL. – Dai