【问题标题】:One ID for every database column, how to do?每个数据库列一个ID,怎么办?
【发布时间】:2010-12-22 13:41:45
【问题描述】:

我正在研究一个食物数据库,每种食物都有一个属性列表(脂肪、能量、维生素等)

这些道具由 50 列不同的蛋白质、脂肪、碳水化合物、维生素、元素等组成。(它们很多)
未来列的数量可能会增加,但不会太多很多,极端情况下为 80
每列都需要单独引用另一个表中整个列表的一个参考书目(需要检查该值是否可靠)。

考虑 ids,应该包含一个数字、一个 NULL val 或 0 用于一个特定的异常引用(将指向另一个表)

我虽然有一些解决方案,但它们彼此非常不同,而且我是 db 的菜鸟,所以我不知道最好的解决方案。

将 value_1 视为蛋白质,将 value_2 视为碳水化合物等。

我认为最好的(我希望)2 个替代方案是:

(1) 创建一个 varchar(255?) 列,包含所有 50 个 id,如下所示:

column energy              (7.00)
column carbohydrates       (89.95)
column fats                (63.12)
column value_bil_ids       (165862,14861,816486) ## as a varchar
etc...

在这种情况下,我可以用“,”将其拆分为一个数组并检查 id,但我仍然担心编码实用性...这可能会节省太多列,但我不知道多少为了可扩展性也可能是实用的。 原则上,我认为这个选项通常用于查询优化(我希望!)

(2) 只需为每个值使用一个额外的 id 列,因此:

column energy                 (7.00)
column energy_bibl_id         (165862)
column carbohydrates          (89.95)
column carbohydrates_bibl_id  (14861)
column fats                   (63.12)
column fats_bibl_id           (816486)
etc...

这似乎是一个重要的列数,但首先要清楚,尤其是对于任何值列和他的ID的关系。

(3) 在值和参考书目后面创建一个关系表,所以

table values
energy
carbohydrates
fats
value_id --> point to table values_and_bibliographies val_bib_id


table values_and_bibliographies
val_bib_id
energy_id        --> point to table bibliographies biblio_id
carbohydrates_id --> point to table bibliographies biblio_id
fats_id          --> point to table bibliographies biblio_id


table bibliographies
biblio_id
biblio_name
biblio_year

我不知道这些是否是最好的解决方案,如果有人能帮助我解决这个问题,我将不胜感激!

【问题讨论】:

标签: php mysql scalability query-optimization


【解决方案1】:

除了 NoSQL 系统外,在 DB 世界中不建议也不流行将更多列附加到表中。

请详细说明你的意图:)

【讨论】:

    【解决方案2】:

    您需要规范化该表。你的所作所为是疯狂的,会导致你的头发松散。它们被称为关系数据库,因此您可以在不添加列的情况下做您想做的事情。您想对其进行结构化以便添加行。

    请使用真实姓名,我们可以抽出一个架构。

    编辑很好的编辑。 #3 正在接近理智的设计。但是您仍然不清楚参考书目在食物模式中的作用!我想这就是你想要的。您可以将食物及其成分链接到参考书目。我认为参考书目就像一个食谱?

    FOODS 
    id name
    1   broccoli
    2   chicken
    
    COMPONENTS
    id name
    1   carbs
    2   fat
    3   energy
    
    BIBLIOGRAPHIES
    id  name           year
    1  chicken soup     1995
    
    
    FOOD_COMPONENTS links foods to their components
    id  food_id component_id bib_id  value
     1   1         1          1       25 grams
     2   1         2          1       13 onces
    

    所以要获取数据,您需要使用联接。

    SELECT * from FOOD_COMPONENTS fc
        INNER JOIN COMPONENTS c on fc.component_id = c.id
        INNER JOIN FOODS f on fc.foods_id = f.id
        INNER JOIN BIBLIOGRAPHIES b on fc.bib_id = b.id
    WHERE
        b.name = 'Chicken Soup'
    

    【讨论】:

    • 感谢您的帮助和您为像我这样的菜鸟所花费的时间,对于不清楚的问题,我很抱歉,我正在学习在网上阅读的数据库并在这里提问,所以我正在学习如何提问获得正确的帮助!参考书目对于我存储的数据的科学性是必要的,如果我写汉堡包在 100 克的样本中含有 85 克脂肪,那么只有参考书目才能证明这是真的。
    • 咳咳,是的,它可能是......我不是英语大师!呵呵
    【解决方案3】:

    您非常需要考虑重新设计您的数据库结构 - 当您想要存储与其相关的其他数据时,不建议继续向表中添加列。

    在关系数据库中,您可以通过使用外键将表相互关联。由于您想存储一堆与您的数据相关的值,请创建一个新表(称为值或其他),然后使用原始表中的 id 作为新表中的外键。

    您提出的这种设计将使编写查询成为一个令人头疼的问题,更不用说假设您不需要填充每一列,您的表中会有大量的空值..

    【讨论】:

      【解决方案4】:

      为什么,看在 $deity 的份上,你是按列来做的吗?那就是疯狂!

      将此表分解为行,然后在每一行上放置一列。如果不知道更多关于这是什么以及为什么会这样,很难说更多。

      【讨论】:

        【解决方案5】:

        这是您可以采取的一种方法,让您可以整天添加属性而无需更改架构:

        表格:食物 - 每一行都是您描述的食物

        • 身份证
        • 姓名
        • 说明
        • ...

        表格:属性 - 每一行都是食物可以具有的数字属性

        • 身份证
        • 姓名
        • 最小值
        • 最大值
        • 单元(可能是一个“重复组”,因此技术上应该在它自己的表中)

        表:参考书目 - 我不知道这是什么,但你知道

        • 身份证
        • ...

        表:FoodAttribute - 每个具有属性的食物实例的一条记录

        • 食物
        • 属性
        • 参考书目
        • 价值

        所以你可能有以下记录

        • 食物 #1 = 芝士汉堡
        • 属性 #1 = 脂肪(单位 = 克)
        • 参考书目 #1 = 与芝士汉堡和脂肪有关的任何内容

        然后,如果一个芝士汉堡有 30 克脂肪,那么 FoodAttribute 表中就会有一个条目,其中 Food 列中为 1,Attribute 列中为 1,Bibliography 列中为 1,Value 列中为 30。

        (注意,您可能需要一些其他机制来处理非数字属性。)

        阅读 Data ModelingDatabase Normalization 以了解有关如何解决这些类型问题的更多信息...

        【讨论】:

          【解决方案6】:

          我多次重读您的问题,我相信您实际上正在尝试使用关系模式,而您关心的是与表关联的列数(您可能提到了 80 个) .我向你保证,从计算的角度来看,一张桌子上有 80 列是可以的。您的数据库可以处理它。从编码的角度来看,它可能很高。

          Proposed (1) 当你想添加一列时会失败。您有效地将所有列存储在逗号分隔的单列中。不好。

          我不明白 (2)。听起来和(3)一样

          (3) 在精神上是正确的,但你的例子是混乱和不清楚的。将您的问题缩减为一个包含五列或其他内容的简单案例,然后编辑您的问题或再次发布。

          简而言之,现在不要担心列数。在优先级列表中排名较低。

          【讨论】:

            【解决方案7】:

            如果您不需要根据您想添加到每条记录的任意键/值对来形成查询,您可以在紧要关头 serialize()/unserialize() 关联数组并将其放入单个字段中

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2015-12-10
              • 2011-02-17
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-03-15
              相关资源
              最近更新 更多