Alw*_*uff 7 database-design sql-server sql-server-2012 subtypes
为了让这个问题对未来的读者有用,我将使用通用数据模型来说明我面临的问题。
我们的数据模型由两个实体组成,它们应标记为A和B。为了简单起见,它们的所有属性都将是int类型。
实体A具有以下属性:D和X;实体B具有以下属性:D和Y;
由于两个实体共享共同的属性D,我决定应用类型/子类型设计。
我不确定我的实现是否正确,因此我在这里要求进行设计审查。
-- lookup table for discriminator column
CREATE TABLE ClassType
(
ClassTypeID INT NOT NULL IDENTITY(1, 1) PRIMARY KEY,
Class_Description VARCHAR(50) NOT NULL
);
-- inserting types A and B from our example
INSERT INTO ClassType (Class_Description)
VALUES ('A'), ('B');
-- creating base class table
CREATE TABLE BaseClass
(
BaseClass_ID INT NOT NULL IDENTITY(1, 1) PRIMARY KEY,
ClassTypeID INT NOT NULL, -- FK to Type
D int
);
ALTER TABLE BaseClass
ADD CONSTRAINT [FK_BaseClass_ClassType]
FOREIGN KEY (ClassTypeID)
REFERENCES ClassType (ClassTypeID);
-- we need this constraint in order for foreign keys in subclasses to work
ALTER TABLE BaseClass
ADD CONSTRAINT [FK_AltKey]
UNIQUE (BaseClass_ID, ClassTypeID);
-- creating subclasses:
CREATE TABLE SubclassA
(
BaseClass_ID INT NOT NULL PRIMARY KEY,
X int,
ClassTypeID AS 1 PERSISTED -- calculated field, ensures integrity
);
ALTER TABLE SubclassA
ADD CONSTRAINT [FK_SubclassA_BaseClass]
FOREIGN KEY (BaseClass_ID, ClassTypeID)
REFERENCES BaseClass (BaseClass_ID, ClassTypeID);
CREATE TABLE SubclassB
(
BaseClass_ID INT NOT NULL PRIMARY KEY,
Y int,
ClassTypeID AS 2 PERSISTED -- calculated field, ensures integrity
);
ALTER TABLE SubclassB
ADD CONSTRAINT [FK_SubclassB_BaseClass]
FOREIGN KEY (BaseClass_ID, ClassTypeID)
REFERENCES BaseClass (BaseClass_ID, ClassTypeID);
Run Code Online (Sandbox Code Playgroud)
这是数据库图表在 SQL Server 2012 中的外观:
INSERT/UPDATE/DELETE?是的,设计看起来很棒。小注:
您可以使用TINYINT, 而不是INTfor ClassTypeID。或者甚至CHAR(1)and have 'A'and'B'而不是1and 2。1 个字节而不是 4个字节意味着您在每行、所有 3 个表和包含的每个索引中节省3 个字节ClassTypeID- 如果ClassTypeID是聚集键的一部分,则这些表上的每个索引都将节省。
基表和子类型表的属性都可以是NOT NULL. 我不明白为什么你会希望它们可以为空,使用这种设计。
如果您同时UNIQUE拥有基表的约束和以相反顺序定义的引用它的 2 个外键,它可能会更好(但需要彻底测试)(ClassTypeID, BaseClass_ID)。这更像是一个索引/物理设计建议,它不会改变逻辑设计。我也会尝试使用此顺序在基表中包含聚集键。