每个数据库列都有一个ID,该怎么办?

时间:2009-12-02 20:10:53

标签: php mysql scalability query-optimization

我在食物数据库上工作,每种食物都有一系列属性(脂肪,能量,维生素等)

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

考虑id,应该包含一个数字,一个NULL值,或者0表示一个特定的异常引用(将指向另一个表)

我虽然有一些解决方案,但是每个人都非常不同,而且我是db的新手,所以我不知道最好的解决方案。

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

我认为最好(我希望)的两种选择:

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

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

我不知道这些是否是最好的解决方案,如果有人能帮我揭开它,我将不胜感激!

7 个答案:

答案 0 :(得分:5)

您需要规范化该表格。你正在做的是疯狂,会让你的头发松散。它们被称为关系数据库,因此您可以在不添加列的情况下执行所需操作。您想要构建它以便添加行。

请使用真实姓名,我们可以制定一个模式。

编辑良好的编辑。 #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'

答案 1 :(得分:2)

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

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

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

答案 2 :(得分:1)

这里有一种方法可以让您整天添加属性而无需更改架构:

表:食物 - 每行都是你描述的食物

  • Id
  • 名称
  • 说明
  • ...

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

  • 编号
  • 名称
  • MINVALUE
  • 的MaxValue
  • 单位(可能是'重复组',因此技术上应该在自己的表中)

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

  • 编号
  • ...

表:FoodAttribute - 具有属性

的食物的每个实例的一条记录
  • 食品
  • 属性
  • 参考书目

所以你可能有以下记录

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

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

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

阅读数据建模数据库规范化,了解有关如何解决这些类型问题的更多信息......

答案 3 :(得分:0)

除了使用NoSQL系统外,不建议在数据库世界中添加更多列到表中。

请详细说明你的意图:)

答案 4 :(得分:0)

为什么,对于美元的爱,你是通过专栏做的吗?那种方式就是疯狂!

将此表分解为行,然后在每行上放置一列。如果不知道这是 的内容以及为什么会这样,那就很难说了。

答案 5 :(得分:0)

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

建议(1)当您想要添加列时将失败。您有效地将所有列存储在逗号分隔的单列中。坏。

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

相同

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

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

答案 6 :(得分:0)

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