【问题标题】:If I have tblBookInfo (bookId, title... etc.) and I want it to have categories column, what is the best way to do it?如果我有 tblBookInfo(bookId、title... 等)并且我希望它有类别列,那么最好的方法是什么?
【发布时间】:2025-12-01 21:55:02
【问题描述】:

如果我有 tblBookInfo(bookId、title...等)并且我希望它有类别列,那么最好的方法是什么?

选项 1

categories 表会有这样的与 bookId 相关的 FK

tblBookInfo
bookId     title
1          test title
2          test title 2
tblCategories
bookId     name
1          Science fiction
1          Mystery
1          Horror
2          Science fiction
2          Mystery

在这种情况下,类别名称会重复多次,很丑

选项 2

像这样在 btlBookInfo 中存储一个 int 数组

tblBookInfo
bookId     title          categories
1          test title     [1,2,3]
2          test title 2   [1,2]

我听说将数组存储在列中并不是here 提出的最佳实践@

选项 3

让类别表保持原样

tblCategories
id     name
1      Science finction
2      Mystery
3      Horror

然后像这样向 tblBookInfo 添加一个 FK

tblBookInfo
bookId     title          categoryId
1          test title     1
2          test title 2   2

最后,添加另一个表,将这些表链接到这样的表

tblCategoryAdapter
bookId     categoryId
1          1
1          2
1          3
2          1
2          2

现在不用重复分类名但我觉得不正常

【问题讨论】:

    标签: sql-server relationship categories jointable


    【解决方案1】:

    通过彻底了解问题域、检查您发现的实体并确保您了解这些实体之间的关系,可以相当简单地确定如何构建数据库。

    这里有两个实体:Book 和 Category。看来您已经从问题域中确定了两条规则:

    1. 一本书可以属于一个或多个类别
    2. 一个类别可以有 1 本书或更多本书

    上面可以简化为“Books和Categories之间存在多对多的关系。”

    在经典的 SQL 数据库引擎中,不可能直接在两个表之间实现多对多关系。它必须通过两个原始表中的每一个与用于交叉引用原始两个表的行的新表之间的1对多或0对多关系来实现。此类表被称为“交叉引用表”、“关系表”、“连接表”或“交集表”。

    在您的情况下,您似乎需要一个表格来交叉引用书籍到类别,反之亦然。

    这可能被图表化(有点糟糕,因为在 Stack Overflow 中很难绘制图表):

    Book <----- Book_Category -----> Category
    

    Book -1-----M- Book_Category -M-----1- Category
    

    因此您需要引入 Book_Category 表(无论您选择什么名称),其中包含 Book 表的外键和 Category 表的外键。

    你可以这样做:

    tblBookInfo

    CREATE TABLE tblBookInfo(
        BookId int not null,
        Name varchar(50) not null,
        CONSTRAINT PK_tblBookInfo PRIMARY KEY CLUSTERED (BookId)
    );
    

    tblCategory

    CREATE TABLE tblCategory(
        CategoryId int not null,
        Name varchar(50) not null,
        CONSTRAINT PK_tblCategory PRIMARY KEY CLUSTERED (CategoryId)
    );
    

    tblBookInfo_Category

    CREATE TABLE tblBookInfo_Category(
        BookId int not null FOREIGN KEY REFERENCES tblBook(BookId),
        CategoryId int not null FOREIGN KEY REFERENCES tblCategory(CategoryId)
    );
    

    【讨论】:

    • 那么...选项 3 是我最好的选择?
    • 我会扩展我的答案。
    最近更新 更多