История изменений
Исправление
stevejobs,
(текущая версия)
:
Тогда уж не «INTEGER с ручной проверкой», а constraint который сам проверит, что установлен один и только один опциональный FK
например, для SQLServer. Допустим, File может принадлежать или Group или User
CREATE TABLE dbo.[Group]
(
ID int NOT NULL CONSTRAINT PK_Group PRIMARY KEY,
Name varchar(50) NOT NULL
);
CREATE TABLE dbo.[User]
(
ID int NOT NULL CONSTRAINT PK_User PRIMARY KEY,
Name varchar(50) NOT NULL
);
CREATE TABLE dbo.File
(
ID int NOT NULL CONSTRAINT PK_File PRIMARY KEY,
OwnerGroup int NULL
CONSTRAINT FK_File_Group FOREIGN KEY REFERENCES dbo.[Group] (ID),
OwnerUser int NULL
CONSTRAINT FK_File_User FOREIGN KEY REFERENCES dbo.[User] (ID),
Subject varchar(50) NULL,
CONSTRAINT CK_File_GroupUser CHECK (
CASE WHEN [Group] IS NULL THEN 0 ELSE 1 END +
CASE WHEN [User] IS NULL THEN 0 ELSE 1 END = 1
)
);
но если система ничего не знает об sql и не можешь поставить constraint, то можно заюзать «эмуляцию наследования»:
если table1 extends table2,table3, то
table1(id, table1-specific stuff)
table1_table2(id, table2-specific stuff)
table1_table3(id, table3-specific stuff)
если select по table1_table2 выдал пустой ответ, то table1 не extends table2
а в нужных местах прослойки самому реализовать referential integrity
чем больше дашь информации движку БД, тем быстрее он будет работать :3
Исходная версия
stevejobs,
:
Тогда уж не «INTEGER с ручной проверкой», а constraint который сам проверит, что установлен один и только один опциональный FK
например, для SQLServer. Допустим, File может принадлежать или Group или User
CREATE TABLE dbo.[Group]
(
ID int NOT NULL CONSTRAINT PK_Group PRIMARY KEY,
Name varchar(50) NOT NULL
);
CREATE TABLE dbo.[User]
(
ID int NOT NULL CONSTRAINT PK_User PRIMARY KEY,
Name varchar(50) NOT NULL
);
CREATE TABLE dbo.File
(
ID int NOT NULL CONSTRAINT PK_File PRIMARY KEY,
OwnerGroup int NULL
CONSTRAINT FK_File_Group FOREIGN KEY REFERENCES dbo.[Group] (ID),
OwnerUser int NULL
CONSTRAINT FK_File_User FOREIGN KEY REFERENCES dbo.[User] (ID),
Subject varchar(50) NULL,
CONSTRAINT CK_File_GroupUser CHECK (
CASE WHEN [Group] IS NULL THEN 0 ELSE 1 END +
CASE WHEN [User] IS NULL THEN 0 ELSE 1 END = 1
)
);
но если система ничего не знает об sql и не можешь поставить constraint, то можно заюзать «эмуляцию наследования»:
если table1 extends table2,table3, то
table1(id, table1-specific stuff) table1_table2(id, table2-specific stuff) table1_table3(id, table3-specific stuff)
если select по table1_table2 выдал пустой ответ, то table1 не extends table2
а в нужных местах прослойки самому реализовать referential integrity
чем больше дашь информации движку БД, тем быстрее он будет работать :3