1

我有一个“ LibraryItem ”,它链接到一个“ Library ”表:

Library-<LibraryItem>-Organisation.

我为许多不同类型的 LibraryItems 使用 LibraryItem 表而且每个LibrayItem都链接到一个组织。我现在意识到我需要提供个人用户库,并且我也可以使用LIbraryItem表来保存个人库项目记录。每条记录都需要一个UserId作为 FK。然而我担心的是这个LibrayItem表现在被用于许多不同的LibraryItem类型,特别是保存系统 LibraryItem记录以及个人记录。也许我不应该担心,因为这就是数据库的意义所在?

思想赞赏,

谢谢。

编辑:

为了简化事情,我可能最终使用不同的 DB 视图,用于 CRUD 操作的不同类型的“LibraryItem”。

4

1 回答 1

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.
)

优点:更少的表,因此更少的连接和更快的查询(通常)

缺点:如果有许多子类,每个子类都有各自的字段,则表变得“稀疏”,可能导致浪费存储空间。即使您只对单个子类感兴趣,也必须始终读取整个行的查询(尽管可以使用非聚集索引来缓解这种情况)。

在每个类型的表 (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 
)  

优点:没有浪费的列,也没有浪费的空间。如果只查询一个子类,则只需要读取属于该子类的数据。

缺点:如果查询多个子类,则必须连接各个表,因此性能会受到影响。

在两种模式之间进行选择是一种平衡行为,取决于许多因素,包括层次结构中有多少子类、这些子类有多少字段以及如何查询数据。

希望这可以帮助。

于 2013-07-09T01:09:14.953 回答