数据库设计 - 选择查询的“单独表与一张表”

use*_*678 1 mysql database

我有一个 MySQL 表,如下所示

书桌

book-id      category    author     author_place       book_name   book_price --------other 50 columns directly related to  book-id              
1           adventure    tom          USA               skydiving     300
2           spiritual    rom         Germany           what you are   500
3           adventure    som         India              woo woo       700
4           education    kom         Italy               boring       900
5           adventure    lom         Pak                 yo yo         90
.
.
4000        spiritual    tom          USA                you are          10
Run Code Online (Sandbox Code Playgroud)

如您所见,大约有 4000 行和 55 列,我主要使用此表进行选择查询,可能会在 2-3 周后添加或更新新书

我对类别和作者列有疑问

现在如果我需要按类别和作者选择表格,我可以简单地做

SELECT * from books Where author = 'tom'

Select * FROM books WHERE category='education'
Run Code Online (Sandbox Code Playgroud)

它工作正常,但根据标准数据库设计,我认为我应该将类别和作者列分成单独的表(尤其是作者),并在书中使用它们的主键作为外键table 类似这样的

书桌

book-id      categ_id    author_id          book_name   book_price --------other 50 columns directly related to  book-id              
1                   1          1             skydiving     300
2                   2          2             what you are   500
3                   1          3             woo woo       700
4                   3          4             boring       900
5                   1          5              yo yo         90
.
.
4000                3          1              you are          10
Run Code Online (Sandbox Code Playgroud)

分类表

categ_id      category_name                
1              advernture         
2              spiritual         
3              education                
.              .
.              .
30             something
Run Code Online (Sandbox Code Playgroud)

作者表

author_id  author      country
 1         tom          USA               
 2         rom         Germany           
 3         som         India             
 4         kom         Italy              
 5         lom         Pak         
Run Code Online (Sandbox Code Playgroud)

但是每次我按作者或类别进行选择查询时,我都必须使用连接表,我认为这会效率低下,像这样

SELECT * FROM Books LEFT JOIN authors on authors.author_id = books.author_id WHERE books.author_id =1
SELECT * FROM Books LEFT JOIN categories on categories.categ_id = books.categ_id_id WHERE books.categ_id =1
Run Code Online (Sandbox Code Playgroud)

那么在这种情况下,我应该将第一个表分成单独的表还是第一个表设计更好?

小智 5

这个问题的答案来自 Edgar F. Codd 先生本人 - 所有RDBMS都建立在其上的关系模型的发明者。

在发布关系模型论文后不久,他和他的团队紧随其后发表了关于所谓范式的论文。它们很少,但前三个(至少)应该被普遍认为是强制性的:

当您阅读它们时,您会发现您的初始设计违反了 2NF,并且您提出了一个或多或少尊重它的解决方案。毫无疑问地继续采用符合 NF 标准的设计。

详细说明您对 Join 性能的担忧。只要满足以下条件,这不是问题:

  • 您的数据库架构设计良好(至少符合 2NF)
  • 您使用外键链接表(MySQL 的文档
  • 你通过他们的 FK 加入桌子
  • 您拥有高效运行数据所需的硬件资源

例如,在带有 InnoDB 的 MySQL 上,在使用外键的 2NF 兼容模式上,FK 的连接性能将是您最不关心的事情之一。

历史上,MySQL 中有一个数据库引擎——MyISAM——不支持外键约束。也许这是关于糟糕的连接性能(当然还有糟糕的模式设计)的主要反馈来源。