【问题标题】:Database design - "Separate Tables Vs One table" for Select Queries数据库设计 - 选择查询的“单独表与一个表”
【发布时间】:2019-08-22 20:16:50
【问题描述】:

我有一个如下的 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

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

我对分类和作者栏目有疑问

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

SELECT * from books Where author = 'tom'

Select * FROM books WHERE category='education'

它工作正常,但根据标准数据库设计,我认为我应该将类别和作者列分开到单独的表中(尤其是作者),并在书中使用它们的主键作为外键 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

分类表

categ_id      category_name                
1              advernture         
2              spiritual         
3              education                
.              .
.              .
30             something

作者表

author_id  author      country
 1         tom          USA               
 2         rom         Germany           
 3         som         India             
 4         kom         Italy              
 5         lom         Pak         

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

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

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

【问题讨论】:

  • 按照您的建议分隔表格(也许还进行其他更改)。如果您明智地使用列索引,则加入的惩罚比您想象的要少得多。当然,您将节省整个数据库占用的空间。
  • @TimBiegeleisen 谢谢,我在某处读到 join 是一项非常昂贵的操作,所以我有这个疑问,谢谢,顺便说一句,你确定我也应该将类别列分开,它实际上只有类别表中的一列
  • 是的,您的类别表对我来说很有意义。您现在可以参考 ID 号,而不是可能庞大的类别字符串。换句话说,您的主表引用adventure 的每个地方现在只需引用数字1。从长远来看,这可以节省空间。如果设置正确,连接还不错。
  • 内容丰富,非常感谢:)

标签: mysql database


【解决方案1】:

这个问题的答案来自 Edgar F. Codd 先生本人 - 所有 RDBMS 所基于的关系模型的发明者。

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

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

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

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

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

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

【讨论】:

  • 感谢详细回答:)
猜你喜欢
  • 2010-11-13
  • 2016-07-05
  • 2011-02-15
  • 2021-12-24
  • 2018-10-28
  • 2012-02-19
  • 1970-01-01
  • 2012-02-26
  • 1970-01-01
相关资源
最近更新 更多