【问题标题】:mySQL table organisation for multi-dimensional categorisation用于多维分类的 mySQL 表组织
【发布时间】:2017-02-16 13:25:03
【问题描述】:

现有系统:

我有一个 mySQL 数据库,它为大约 200 个不同的唯一用户存储类别相关信息。为每个用户存储和检索的信息在层次结构中

imageCategories
    > Parent Category 1
        > Child Category 1 : "45,19,3,4,8"
        > Child Category 2 : "17,1,99"
        > ... etc
    > Parent Category 2
        > Child Category 1 : "83,6"
        > Child Category 2 : "19,74,26"
        ... etc
    > etc

每个子类别的字符串值是一系列以逗号分隔的 id,它们引用存储在该子类别下的描述(在单独的表中)。我通过以下形式的 json_encoded 字符串将所有这些作为数组存储在每个用户的列中:

{"Parent Category 1":{"Child Category 1":["45,19,3,4,8"],"Child Category 2":["17,1,99"]},"Parent Category 2":{"Child Category 1":["83,6"],"Child Category 2":["19,74,26"]}}

系统通过在用户登录时检索此 json_string 并将其解码为会话数组来工作。每当对其进行任何更改时,都会将其重新编码为 json 字符串,保存到数据库中,并更新会话数组以反映这一点。这工作正常。虽然我的研究早在让我这样做的时候,我就不太确定在 mySQL 中存储多维数组是否是好的最佳实践。我所知道的是,这样可以毫无压力地组织它,而且我没有注意到它会导致很多开销,但这并不是说它不会。


难题:

我现在要做的是为数据库中的每个子类别添加一个字符串描述。以后可能会出现在每个父类别中,但要先进行婴儿步骤。

我最初打算为整个数组创建第三个维度。而不是:

"Child Category Key" : "id string"

我会改成:

"Child Category Key" : ["id string", "description string"]

或:

"Child Category Key" : ["id string", id for description on another table]

我认为两者都没有问题,但我想知道我是否偏离了最佳实践。我是否应该为整个类别结构创建一个新表,而不是将所有这些作为 json 字符串存储在具有其他用户设置的列中(就字符长度而言,它永远不会变得过于笨拙)。当前的结构很容易让我理解,如果它的结构使管理数据库变得不必要地复杂,我不一定会跳到一个可以提供最小开销收益的解决方案(请记住,我们中的一些人不是天生的,并且我们的大脑处理这种结构的速度比其他人慢)。


设计要求:

我可能会错过描述所需的细节,因为我不确定哪些信息最相关。我可以在需要的地方详细说明。似乎最重要的设计要求是每个用户都有唯一的类别键和值。它们只能采用parent > child > csv of ids 的形式,但每个用户都有自定义键标题和不同的编号。每个的顺序也很重要。

我目前正在一台带有 ssd 磁盘、1gb 内存和来自 Intel hexcore 的单个 2ghz 内核的服务器上运行。对数据库的请求主要是在前端和后端检索类别。大多数人使用很少的流量,所以除了偶尔的高峰之外没有什么太费力了。当我看到瓶颈临近时,我会升级。只是尝试尽可能高效地使用我目前拥有的东西并保持最佳实践。


数据库结构:

现在我的表结构是(省略与问题无关的其他列):

表格用户设置:

+-----+----------------------+-----+
| id  |   imageCategories    | ... |
+-----+----------------------+-----+
|   1 | {"Parent Category... | ... |
|   2 | {"Parent Category... | ... |
|   3 | {"Parent Category... | ... |
| ... |                      |     |
+-----+----------------------+-----+

表用户:

+-----+----------------------+---------+--------+
| id  |   username           | cluster | server |
+-----+----------------------+---------+--------+
|   1 | johndoe              |       1 |      1 |
|   2 | katedoe              |       1 |      1 |
|   3 | ellendoe             |       1 |      1 |
| ... |                      |         |        |
+-----+----------------------+---------+--------+

表格描述_0001:

+-----+---------+---------------+-----+
| id  |  title  | descriptions  | ... |
+-----+---------+---------------+-----+
|  11 | Title 1 | Description 1 | ... |
|  56 | Title 2 | Description 2 | ... |
|  78 | Title 3 | Description 3 | ... |
| ... |         |               |     |
+-----+---------+---------------+-----+

users 中的每个 usersettings 条目都有相同的行,并且具有匹配的 id。因此,他们的用户名等总是可以通过知道自己的 ID 号从用户设置中引用。目前我只有一个数据库,但为了在一定程度上证明它的未来,我将描述存储在一个表中,其名称中有一个索引,每个用户都有一个集群编号值和一个服务器编号值。每个用户平均有大约 100 行描述,因此目前将达到 20,000 行。当这造成瓶颈时,我将启动一个 descriptions table 0002,然后如果需要,再启动第二台服务器。也许我的工作流程很幼稚,但它似乎应该有所帮助。


总结:

所以总而言之,我应该通过以下方式调整我的类别数组以存储子类别的字符串描述:

  1. 使子类别键具有数组值而不是 当前字符串值,包含当前字符串值和 附加字符串描述。

  2. 与 1 类似,但将字符串描述设为引用的 ID 号 新表上的字符串

  3. 看看根本不使用json编码的数组,移动整个 类别结构到自己的表中

  4. 为父类别创建一个表,为子类别创建一个表,为 csv 内容创建一个表。在每个中包括一个描述列(根据上面的难题)和一个订单列(必要的,根据上面的设计要求) - 或者是否有更好的方法来存储订单而不是在表格将检索和更新每个相关行的订单列时包含多个用户的唯一类别信息?听起来可能需要很多开销。

【问题讨论】:

  • 几乎不可能为我们不知道设计应该满足什么要求的任何事物提出设计建议。所有方法都有其优点和缺点。没有人可以根据这么少的信息负责任地提出任何设计。
  • 抱歉,我认为在提供用户编号、行号和表格结构时,我已经彻底了解了我应该在哪里。如果进一步的建议只会提供更具体的细节,我可以将其解释为没有犯任何明显的普遍错误。这对我有用。如果某个特定区域缺乏细节,我可以提供一些。我会添加我现在能想到的任何其他内容。

标签: php mysql arrays json database


【解决方案1】:

我最终找到了一个类似于 (4) 的解决方案。我也更好地理解现在描述设计要求的重要性,因为导致我做出这个决定的原因是意识到它在处理中更有效(我相信?)并且更容易理解一次使用层次结构的选定级别。

例如,如果我正在处理父类别 2、子类别 1 下的所有描述,我只需在具有共享标识符的描述表中获取或插入所有描述,而不是处理包含所有层次结构的多维数组.后者使在数据库中组织用户更容易,但分类变得足够大,以至于我认为它确实需要为层次结构的每个级别提供单独的表。在很多情况下,我只使用分类层次结构的一个孤立级别,将整个分类放入单个 md 数组感觉是更糟糕的选择。

就开销差异而言,我现在不确定。在 php 中发生的数组排序较少以隔离我需要的数据,但对 db 的调用要多得多。

我在理解设计要求方面犹豫不决(仍然没有就此给出全面的答案)是因为我是大型用户数据库的新手,不擅长预测需求。我正在以一种对我来说感觉可扩展的方式来设计它,因此,层次结构的每个级别的表感觉最不繁琐(在繁琐的设置之后 - 我目前正在重做大量代码来制作功能与新设置一起工作)并且随着需求的变化更具可扩展性。

【讨论】:

    猜你喜欢
    • 2012-04-21
    • 2021-12-12
    • 1970-01-01
    • 2018-05-05
    • 2016-02-24
    • 1970-01-01
    • 1970-01-01
    • 2014-04-19
    • 2015-06-07
    相关资源
    最近更新 更多