【问题标题】:How to store data with large number (constant) of properties in SQL如何在 SQL 中存储具有大量(常量)属性的数据
【发布时间】:2011-12-08 13:07:03
【问题描述】:

我正在解析美国农业部的食品数据库并将其存储在 SQLite 中以供查询。每种食物都含有相同的 162 种营养素。似乎营养素列表(名称和单位)已经有一段时间没有改变了,因为这是一个爱好项目,我不希望出现任何突然的变化。但每种食物都有与每种营养素相关的独特数量。

那么,如何合理地存储此类信息。我的优先事项是多编程语言友好(Python 和 C++ 优先),作为编码人员的我的理智,以及随着时间的推移轻松检索营养集以求和或绘图。

到目前为止,我想到的两件事是 162 列(我不是特别喜欢,但它确实使查询更简单),或者一个食物表,它有一个指向 nutrition_list 表的链接,然后链接到带有营养名称和单位的静态表。如果我的期望是错误的,第二个似乎更灵活,但我什至不知道从哪里开始编写求和和时间序列的查询。

谢谢

【问题讨论】:

  • 第二种方法是明智的。
  • Magnus Lie Hetland 的“Python 入门:从新手到专业人士”有一节展示了如何使用 Python 和 sqlite 创建数据库应用程序。幸运的是,he uses the USDA nutrient database for the example.
  • 两个(当前)答案都是正确的恕我直言,但我要补充一点,您应该在 Food 和 Nutrient 外键列的“FoodNutrients”表上放置一个唯一索引。该索引不仅可以加快您的查询速度,还可以防止您为相同类型的食物插入相同的营养素。

标签: c++ python sql sqlite


【解决方案1】:

您应该阅读一下database normalization。大多数规范化的东西都非常直观,但真正了解步骤的定义并查看示例有助于理解概念,并且如果您将来想设计数据库,将对您有很大帮助。

至于这个问题,我建议你使用3张表:一张用于食物(我们称它为foods),一张用于营养素(nutrients),一张用于每种食物的特定营养素(@ 987654324@).

foods 表应该有一个唯一的索引供参考和食物的名称。如果食物有其他相关数据(可能是图片或描述的链接),这些数据也应该放在此处。每个单独的食物将在此表中占一行。

营养素表还应该有一个唯一的参考索引和营养素的名称。您的 162 种营养素中的每一种都将在此表中占一行。

然后你就有了包含每种食物营养价值的交叉表。此表包含三列:food_idnutrient_idvalue。每种食物在此表内有 162 行,每种营养素对应 oe。

这样,您可以根据需要添加或删除营养和食物,并独立于编程语言查询所有内容(好吧,使用 SQL,但无论如何您都必须使用它:))。

让我们尝试一个例子。 foods 表中有 2 种食物,nutrients 表中有 3 种营养素:

+------------------+
| foods            |
+---------+--------+
| food_id | name   |
+---------+--------+
| 1       | Banana |
| 2       | Apple  |
+---------+--------+

+-------------------------+
| nutrients               |
+-------------+-----------+
| nutrient_id | name      |
+-------------+-----------+
| 1           | Potassium |
| 2           | Vitamin C |
| 3           | Sugar     |
+-------------+-----------+

+-------------------------------+
| foods_nutrients               |
+---------+-------------+-------+
| food_id | nutrient_id | value |
+---------+-------------+-------+
| 1       | 1           | 1000  |
| 1       | 2           | 12    |
| 1       | 3           | 1     |
| 2       | 1           | 3     |
| 2       | 2           | 7     |
| 2       | 3           | 98    |
+---------+-------------+-------+

现在,要获取香蕉的钾含量,您需要查询:

SELECT food_nutrients.value
  FROM food_nutrients, foods, nutrients
  WHERE foods_nutrients.food_id = foods.food_id
    AND foods_nutrients.nutrient_id = nutrients.nutrient_id
    AND foods.name = 'Banana'
    AND nutrients.name = 'Potassium';

【讨论】:

    【解决方案2】:

    使用第二种(更规范化的)方法。

    您甚至可以使用比您提到的更少的桌子:

    • tbl营养素
      -- 营养ID
      -- 营养素名称
      -- NutrientUOM(计量单位)
      -- 其他

    • tblFood
      -- 食物编号
      -- 食物名称
      -- 其他

    • tblFoodNutrients
      -- FoodID (FK)
      -- NutrientID (FK)
      -- UOMCount

    维护一个 160 多个字段的数据库将是一场噩梦。

    如果还涉及时间元素(测量值会改变吗?),那么您可以根据可能发生的变化将日期字段添加到营养素和/或食物营养素表中。

    【讨论】:

    • 时间元素有点成直角,我可能不应该提起它。还将有一个“膳食”数据库,其中包含日期和指向食物列表和数量的链接。所以时间序列将是膳食数量乘以食物总和。
    猜你喜欢
    • 2015-06-27
    • 1970-01-01
    • 1970-01-01
    • 2010-11-29
    • 2015-12-04
    • 2016-10-23
    • 1970-01-01
    • 1970-01-01
    • 2013-07-08
    相关资源
    最近更新 更多