Можно ли обеспечить целостность базы данных на основе косвенных отношений - PullRequest
1 голос
/ 04 мая 2020

У меня есть Thing с, которые имеют Type. У меня также есть эти Token, которые связаны с Type. Теперь я хочу сказать, что Thing имеет комбинацию Token с. Возможное представление таблицы может быть:

| Thing |  | Type |  | Token |  | TypeToken |  | ThingToken |
|-------|  |------|  |-------|  |-----------|  |------------|
| Id    |  | Id   |  | Id    |  | TypeId    |  | ThingId    |
| Type  |  |------|  |-------|  | TokenId   |  | TokenId    |
|-------|                       |-----------|  |------------|

. Для целостности базы данных я хотел бы обеспечить, чтобы Thing мог иметь только Token s, если они ранее были связаны с Type. Каким будет мой лучший вариант?

Ответы [ 2 ]

3 голосов
/ 04 мая 2020

Один из способов сделать это - добавить TypeId в таблицу ThingToken, чтобы вы могли использовать его во внешних ключах. Вам также необходимо дополнительное уникальное ограничение для Thing, но вы можете включить его (TypeId, Id), чтобы оно также было полезно для поиска по TypeId и физически идентично некластерному индексу для just (TypeId).

EG:

use tempdb
go

drop table if exists ThingToken
drop table if exists TypeToken
drop table if exists Token
drop table if exists Thing
drop table if exists Type
--| Thing |  | Type |  | Token |  | TypeToken |  | ThingToken |
--|-------|  |------|  |-------|  |-----------|  |------------|
--| Id    |  | Id   |  | Id    |  | TypeId    |  | ThingId    |
--| Type  |  |------|  |-------|  | TokenId   |  | TokenId    |
--|-------|                       |-----------|  |------------|

create table Type(Id int primary key)
create table Token(Id int primary key)
create table TypeToken
(
  TypeId int not null references Type, 
  TokenId int not null references Token,
  constraint pk_TypeToken
    primary key (TypeId,TokenId)
)

create table Thing
(
  Id int not null primary key, 
  TypeId int references Type,
  constraint ak_Thing
    unique (TypeId,Id)
)

create table ThingToken
(
  ThingId int not null,
  TokenId int not null,
  TypeId int not null,
  constraint pk_ThingToken 
     primary key (ThingId,TokenId),
  constraint fk_ThingToken_Thing 
    foreign key (TypeId,ThingId) references Thing(TypeId, Id),
  constraint fk_ThingToken_TypeToken 
    foreign key (TypeId,TokenId) references TypeToken(TypeId, TokenId)
)
1 голос
/ 04 мая 2020

Да, вы можете! Вот пример того, что вам нужно,

CREATE TABLE Foo (
    FooId INT
,   Value VARCHAR(10)
)
CREATE TABLE Bar (
    BarId INT
,   FooId INT
,   Value VARCHAR(10)
)
GO
CREATE FUNCTION CheckFooExistsOnBar
(
    @FooId INT
)
RETURNS BIT
AS
BEGIN
    DECLARE @Response BIT = 0;

    IF EXISTS (SELECT * FROM Bar WHERE FooId = @FooId)
        SET @Response = 1;

    RETURN @Response
END
GO

ALTER TABLE Foo
ADD CONSTRAINT CHK_FooId_Foo
CHECK (dbo.CheckFooExistsOnBar(FooId) = 1)

INSERT INTO Foo (FooId, Value) VALUES (1, '')

Excpt

Проверить еще

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...