我有一个“ LibraryItem ”,它链接到“图书馆”表:
Library-<LibraryItem>-Organisation.
我将 LibraryItem 表用于许多不同类型的 LibraryItems ,并且每个 LibrayItem 都链接到组织。我现在意识到我需要提供个人用户库,我也可以使用 LIbraryItem 表来保存 Personal Library Item 记录。每条记录都需要 UserId 作为FK。但是我关心的是这个 LibrayItem 表现在被用于许多不同的 LibraryItem 类型,特别是持有系统LibraryItem 记录以及个人记录。也许我不应该担心这是数据库的意思?
赞赏,
感谢。
编辑:
为简化起见,我可能最终使用不同的数据库视图,针对不同类型的“LibraryItem”进行CRUD操作。
答案 0 :(得分:0)
在ORM世界中,有两种常见的方法来映射继承层次结构。您没有提到使用ORM,但这些模式无论如何都适用。
您有一个LibraryItem,然后是PersonalLibraryItem和SystemLibraryItem,它们都是LibraryItem的类型。
在每层次表(TPH)映射中,映射到单个表的整个继承层次结构。这里有一个LibraryItemtable来保存PersonalLibraryItem和SystemLibraryItem。
CREATE TABLE LibraryItem
(
ID INT NOT NULL PRIMARY KEY, -- Shared by all types
Title NVARCHAR(100) NOT NULL, -- Shared by all types
UserID INT NULL -- Only used by PersonalLibraryItem, and therefore is NULLable.
SystemItemAttr INT NULL -- Only used by SystemLibraryItem, and therefore is NULLable.
)
优点:更少的表,更少的连接和更快的查询(通常)
缺点:如果有许多子类,每个子类都有各自的字段,那么该表将变为&#34;稀疏&#34;可能导致存储空间浪费。查询整个行时,即使您只对单个子类感兴趣,也必须始终读取(尽管可以使用非聚簇索引进行缓解)。
在每个类型的表(TPT)映射中,继承层次结构中的每个类型都映射到其单独的表,并且所有表都通过公共ID链接:
CREATE TABLE LibraryItem
(
ID INT NOT NULL PRIMARY KEY, -- Shared by all types
Title NVARCHAR(100) NOT NULL, -- Shared by all types
)
CREATE TABLE PersonalLibraryItem
(
ID INT NOT NULL PRIMARY KEY, -- Shared by all types
UserID INT NOT NULL -- Note NOT NULL
)
CREATE TABLE SystemLibraryItem
(
ID INT NOT NULL PRIMARY KEY, -- Shared by all types
SystemItemAttr INT NOT NULL -- Note NOT NULL
)
优点:没有浪费的列,没有浪费的空间。如果仅查询一个子类,则只需读取属于该子类的数据。
缺点:如果查询多个子类,则必须连接各个表,因此性能会受损。
在两种模式之间进行选择是一种平衡行为,取决于许多因素,包括层次结构中有多少个子类,这些子类有多少个字段,以及如何查询数据。
希望这有帮助。