mysql - 如何正确为mysql中的表添加相关属性

标签 mysql sql database-design

我们在我的工作地点开发该系统已经有一段时间了,我觉得数据库设计有点失控了。

例如,我们有一个表格小部件(我在某种程度上欺骗了它们):

+-----------------------+
|        Widget         |
+-----------------------+
| Id | Name     | Price |
| 1  | Sprocket | 100   |
| 2  | Dynamo   | 50    |
+-----------------------+
*There's about 40+ columns on this table already

我们希望为每个小部件添加一个属性以用于打包信息。我们需要知道它是否有包装信息,如果没有包装信息,或者我们不知道它是否有包装信息。然后,我们还需要存储包装详细信息的类型(假设它存在,或者可能不存在,并且现在它是冗余信息)。

我们已经有另一个表来存储详细信息信息(我个人认为这个表应该被划分,但这是另一个问题)。 PD = 包详细信息

+--------------------------------+
|       System Properties        |
+--------------------------------+
| Id  | Type     | Value          |
| 28  | PD       | Boxed          |
| 29  | PD       | Vacuum Sealed  |
+--------------------------------+
*There's thousands of rows in the table for all system wide table properties

我会本能地创建许多映射表来捕获这些信息。然而,我被指示在每个表上添加另一列以避免进行联接。

我的解决方案:

创建表:

+---------------------------------------------------+
|                widgets_packaging                  |
+---------------------------------------------------+
| Id | widget_id | packing_info | packing_detail_id |
| 1  | 27        | PACKAGED     | 2                 |
| 2  | 28        | UNKNOWN      | NULL              |
+---------------------------------------------------+

+--------------------+
|     packaging      |
+--------------------+
| Id |               |
| 1  | Boxed         |
| 2  | Vacuum Sealed |
+--------------------+

如果我想知道小部件有什么包装,我会加入到 widgets_packaging,如果我想知道确切的细节,我会再次加入到打包。因此,小部件表上不再有列。

然而,我被告知忽略这一点,并将包装信息的值 int 和另一个值作为系统属性表的外键来查找包装详细信息。因此,向表中添加另外两列,并在系统属性表中创建更多行来存储包详细信息。

+------------------------------------------------------------+
|                           Widget                           |
+------------------------------------------------------------+
|  Id | Name      |Price | has_packaging | packaging_details |
|  1  | Sprocket  |100   | 1             |  28               |
|  2  | Dynamo    |50    | 0             |  29               |
+------------------------------------------------------------+

这样做的原因是,如果您只想知道小部件是否有包装(有很多小部件),那么它更简单并且不涉及连接。他们担心更多的连接会减慢速度。

这里哪个是更正确的解决方案?他们对速度的担忧是否合理?我的直觉是,我们不能只是继续向小部件表添加列,因为它目前正在随着属性标志的不断增长而增长。

最佳答案

这个问题的答案实际上取决于使用该数据库的应用程序是读密集型还是写密集型。如果它是读取密集型的,那么非规范化结构是更好的方法,因为您可以利用索引。选择速度也更快,连接也更少。

但是,如果您的应用程序是写入密集型的,则标准化是更好的方法(您建议的结构是更标准化的方法)。表往往较小,这意味着它们有更好的机会适合缓冲区。此外,规范化往往会减少数据的重复,这意味着更新和插入只需要在一个地方完成。

总结一下:

写入密集 --> 标准化

  • 较小的表更有可能装入缓冲区
  • 重复数据更少,这意味着更新/插入更快

精读 --> 反规范化

  • 更好的索引结构
  • 更少的连接意味着更好的性能

如果您的应用程序不太注重读取而不是写入,那么更混合的方法会更好。

关于mysql - 如何正确为mysql中的表添加相关属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34927924/

相关文章:

php - 记录每月用户上传到我们的网络应用程序的最佳方式是什么?

mysql - 哪个更好地控制状态和执行查询? 1 个 TINYINT 列、1 个 BIT(8) 列或 8 个 BIT(1) 列

php - 插入子行

mysql - 无法使用内连接从表中删除数据

database - 双时态 NoSQL 数据库是否有任何设计模式?

MYSQL Query比较两个查询的结果?

sql - 使用 sp_executesql 在不执行查询的情况下计算查询结果

php - 调和得墨忒耳定律与模型

sql - 我怎样才能使这个 MySQL 查询工作?

php - 在两 (2) 个日期之间,列的日期格式为 (Y-m-d)