如果我有tblBookInfo(bookId,title等),并且希望它具有Categories列,那么最好的方法是什么?
类别表将具有与bookId相关的FK,像这样
tblBookInfobookId title
1 test title
2 test title 2
tbl类别
bookId name
1 Science fiction
1 Mystery
1 Horror
2 Science fiction
2 Mystery
在这种情况下,类别名称将重复很多次而且很丑
像这样在btlBookInfo中存储一个int数组
tblBookInfobookId title categories
1 test title [1,2,3]
2 test title 2 [1,2]
我听说here
并不是将数组存储在列中的最佳做法像这样保留类别表
tbl类别id name
1 Science finction
2 Mystery
3 Horror
像这样向tblBookInfo添加一个FK
tblBookInfobookId title categoryId
1 test title 1
2 test title 2 2
最后,添加另一个将这些链接到此类表的表
tblCategoryAdapterbookId categoryId
1 1
1 2
1 3
2 1
2 2
现在我不必重复类别名称,但是我不认为这是否正常
答案 0 :(得分:1)
通过对问题域的透彻了解,检查发现的实体并确保了解这些实体之间的关系来确定如何构建数据库非常简单。
在这里,您有两个实体:Book和Category。看来,您已经从问题域中确定了两个规则:
以上内容可以简化为“书籍和类别之间存在多对多关系。”
在经典的SQL数据库引擎中,不可能直接在两个表之间实现多对多关系。它必须通过两个原始表中的每一个之间的一对多或0对多关系来实现,该关系与一个新表用于交叉引用原始两个表的行。这些表被称为“交叉引用表”,“关系表”,“联接表”或“交叉表”。
在您的情况下,您似乎需要一个表来将“书籍”与“类别”进行交叉引用,反之亦然。
这可能以图表的形式表示(由于在堆栈溢出中很难绘制,所以有点糟糕):
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)
);