这是我的朋友在接受亚马逊电话采访时被问到的问题。设计一个关系数据库来记录书籍,书籍可以有多个作者,作者可以出版多本书籍。他被要求设计关系(表)和每个属性的类型(无论是文本,字符串等) 问题是他们还希望能够搜索作者姓名和书名。 我知道这样的事情效率不高:
Table Autor
AutorID AuthorName booksIDs(Text) Example:15, Morris Mano:11,56,234
Table Book
BookID Booktitle AuthorsID(Text) Example: 11:Computer Architecture: 15,34,88
在这里使用哪种其他类型更好,而不是为这些属性键入Text?
答案 0 :(得分:2)
基本的第三范式是使用交集表的类似的东西。在关系表中存储以逗号分隔的值总是一个错误。
CREATE TABLE author (
authorID integer primary key,
authorName varchar2(100)
);
CREATE TABLE book (
bookID integer primary key,
bookTitle varchar2(100)
);
CREATE TABLE author_book (
authorID integer,
bookID integer,
constraint pk_author_book primary key( authorID, bookID )
);
现在,实际上,您几乎肯定会将作者姓名分为名字,姓氏等,以方便搜索。如果您使用的是Oracle,则可能需要创建Oracle Text索引以便于搜索。如果您是亚马逊,您可能希望创建一些辅助表,以便于搜索不同表中的属性。
答案 1 :(得分:2)
我会这样做的:
Author (AuthorId, AuthorName, etc.)
PK: AuthorId
Book (BookId, BookName, ISBN, Edition, etc)
PK: BookId
AuthorBooks (AuthorId, BookId)
PK: (AuthorId, BookId)
FK: AuthorId from Author, BookId from Book (thanks to Justin's answer for reminding to add this)
Another index on BookId to facilitate quick search by BookId.
Note that the PK index can be used to search on AuthorId.
添加新书:
按作者姓名搜索(假设作者姓名不是唯一的):
SELECT ab.*, b.*
FROM AuthorBook ab, author a
WHERE ab.AuthorId IN (SELECT AuthorId
FROM Author
WHERE AuthorName = ?)
并且类似于按书名搜索...
答案 2 :(得分:1)
您应该使用关系表将作者与书籍联系起来,而不是在每个表格中列出ID列表。
CREATE TABLE author_book (
author_id INT,
book_id INT,
UNIQUE KEY (author_id, book_id)
);
要获取作者的书籍或书籍的作者,请使用3方式连接,例如
SELECT BookTitle
FROM Book b
JOIN author_book ab ON b.BooKID = ab.book_id
JOIN Author a ON a.AuthorID = ab.author_id
WHERE AuthorName = 'John Smith';