每个层次结构带有外键的表格-最佳做法

问题描述 投票:0回答:0

我试图找出如何最好地在SQL中建模以下场景。 我正在使用C#和Entity Framework。

我有多个需要文件的不同实体。 这是一些伪代码定义方案:

CategoryPage {
    string Name;
    Content Content;
    CategoryImage Image;
}

StaticContentPage {
    string Name;
    Content Content;
    BannerImage Banner;
}

ProductPage {
    string Name;
    Content Content;
    ProductImage[] Images;
}

Content {
    string Value;
    ContentFile[] Files;
}

File {
    FileData Data;
}

CategoryImage : File {
    CategoryPage Category;
}

BannerImage : File {
    StaticContentPage Page;
}

ProductImage : File {
    ProductPage Product;
    int SortOrder;
    bool IsPrimary;
}

ContentFile : File {
    Content Content;
}

FileData {
    byte[] Data;
}

内容被分解为一个单独的实体,因为我想拥有更高级的功能,例如变更跟踪/历史记录,并希望它对任何内容部分都可以使用相同的功能。 任何内容部分所需的其他文件(图像,PDF下载等)都可以上传到该内容部分。


据我了解,外键应该位于依赖于另一个的实体中。 上面所有带有文件/图像的实体都不需要它们( CategoryPage是完全有效的,没有图像, ProductPage可能没有添加任何图像, Content部分可能不需要任何其他文件),所以我想出了FK应该在File实体上。 所以我用一个鉴别符做了一个表每个层次结构的配置:

Files
-----
Id
Discriminator
FileDataId
CategoryPageId
StaticPageId
ProductPageId
SortOrder
IsPrimary
ContentId

这是处理此问题的正确方法吗? 一方面,我之所以喜欢它,是因为当页面被删除时,它会级联到文件中并删除它们,而无需任何其他域逻辑来捕获它。 另一方面,我担心它会增加不必要的复杂性并可能导致性能问题。

我也遇到了TSQL不喜欢的多个级联路径的问题(我没有在上面显示,但是我将Content实体分解为与File实体类似的方式,因此当您删除Category页面时,它会级联到File表和Content表,然后再次从Content表到File表)。

拥有一个通用的File实体,将FK保持在消费者方面(即CategoryPageStaticContentPageProductPageContent实体),并处理我的域层中的删除逻辑,会更好吗? 还是为每种文件类型使用单独的表会更好? 还是我没有想到的另一种方式?

c# sql entity-framework tsql database-design
© www.soinside.com 2019 - 2024. All rights reserved.