【问题标题】:I need some help optimizing my database schema我需要一些帮助来优化我的数据库架构
【发布时间】:2026-01-21 18:35:01
【问题描述】:

这是我的数据布局:

Heading 1:
   Sub heading
   Sub heading
   Sub heading
   Sub heading
   Sub heading

Heading 2:
   Sub heading
   Sub heading
   Sub heading
   Sub heading
   Sub heading

Heading 3:
   Sub heading
   Sub heading
   Sub heading
   Sub heading
   Sub heading

Heading 4:
   Sub heading
   Sub heading
   Sub heading
   Sub heading
   Sub heading

Heading 5:
   Sub heading
   Sub heading
   Sub heading
   Sub heading
   Sub heading

这些标题需要有一个与用户 ID 相关联的“完成状态”布尔值。

目前,我的桌子是这样的:

id  |  userID  |  field_1  |  field_2  |  field_3  |  field_4  | etc...
-----------------------------------------------------------------------
1   |     1    |    0      |     0     |     1     |     0     |
-----------------------------------------------------------------------
2   |     2    |    1      |     0     |     1     |     1     |

每个字段代表一个子标题。在我的表中有这么多列看起来效率非常低...

我该如何优化呢?我想不出任何办法来整理它:/

【问题讨论】:

    标签: mysql sql optimization database-design


    【解决方案1】:

    不要使用布尔值,而是使用简单的关系:

    table completion_status

    id user_id field_id
    
    1  1       3
    2  2       1
    3  2       3
    4  2       4
    ...
    

    由此很容易看出用户 1 完成了字段 3,用户 2 完成了字段 1、3 和 4。

    这样您就不必在想要更改字段数量时更改数据库架构。

    【讨论】:

    • 一开始我使用了类似的方法,但表最终为一个用户提供了 27 行。这个数字将来可能会增长。这不坏吗?我不应该尽量限制表格大小吗?
    • 是的。但是这种方式,你只使用有数据的行——你的方式,你有很多未使用的列。另外,想象一下必须添加一个新类型 - 这样一眨眼 - 你的方式将涉及更改表和查询。
    • 我不认为同一用户有多行是一个问题。现代 DBMS 可以毫无问题地处理数百万行。只需确保添加正确的索引即可。
    • 不,这还不错,只要您定义正确的索引。看看this Wikipedia article on first normal form
    • @Steffan,在您的情况下,行数没有任何意义。实际上,这样您最终会 节省 空间,因为在您的示例中,所有用户都将所有字段定义为 0 或 1。使用我提出的解决方案,用户的字段将只占用最低要求的空间。
    【解决方案2】:

    您可以将子标题放在不同的表格中,然后将该表格链接到第一个表格。

    id  |  userID  |  field_id | 
    -----------------------------
    1   |     1    |    0      | 
    -----------------------------
    2   |     2    |    1      | 
    

    field 看起来像这样

    id  | field_1 | field_2   | etc..
    -----------------------------
    1   |     1   |    0      | etc..
    

    【讨论】:

    • 这并没有真正改变任何东西,只是将数据分成两个表。列过多的问题依然存在。
    【解决方案3】:

    你为什么不做一张这样的桌子?

    id  | User Id | Field ID | Status
    ---------------------------------
    1   |   1     |   1      | 0   
    2   |   1     |   2      | 1  
    

    您可以为具有字段名称的字段创建另一个主表

    【讨论】:

    • 不需要status,如果field_id存在则完成,否则不存在。
    • 好吧,如果您决定稍后添加“进行中”状态,这将有所帮助。 :)