如何在SQL中存储具有大量(常量)属性的数据

How to store data with large number (constant) of properties in SQL

本文关键字:常量 属性 数据 SQL 存储      更新时间:2023-10-16

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

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

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

谢谢

您应该阅读一些关于数据库规范化的内容。大多数规范化的东西是相当直观的,但真正通过步骤的定义和看一个例子有助于理解概念,并将极大地帮助你,如果你想在未来设计一个数据库。

对于这个问题,我建议你用3张表:一张是食物表(姑且称之为foods),一张是营养成分表(nutrients),一张是每种食物的特定营养成分表(foods_nutrients)。

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

营养素表也应该有一个唯一的索引来引用和营养素的名称。你的162种营养物质中的每一种都将在这个表格中得到一行。

然后是包含每种食物营养值的交叉表。该表有三列:food_idnutrient_idvalue。每种食物在这个表中有162行,每一行代表一种营养物质。

这样,你就可以随心所欲地添加或删除营养和食物,并且可以独立于编程语言查询所有内容(好吧,使用SQL,但无论如何你都必须使用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';

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

你甚至可以使用比你提到的更少的表:

  • tblNutrients
    ——NutrientID
    ——NutrientName
    ——NutrientUOM(计量单位)
    ——

  • tblFood
    ——FoodId
    ——FoodName
    ——

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

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

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