Как хранить данные с большим количеством (постоянных) свойств в SQL - PullRequest
1 голос
/ 08 декабря 2011

Я анализирую продовольственную базу данных USDA и сохраняю ее в SQLite для целей запроса.С каждым продуктом связано количество одинаковых 162 питательных веществ.Похоже, что список питательных веществ (название и единицы) не изменился довольно давно, и, поскольку это хобби-проект, я не ожидаю каких-либо внезапных изменений.Но у каждого продукта есть уникальное количество, связанное с каждым питательным веществом.

Итак, как можно разумно хранить такую ​​информацию.Мои приоритеты - совместимость с несколькими языками программирования (предпочтение отдается Python и C ++), здравомыслие для меня как программиста и простота извлечения наборов питательных веществ для суммирования или построения графика с течением времени.

Две вещи, о которых я думал такдалеко было 162 столбца (которые мне не особо нравятся, но это делает запросы проще), или таблица продуктов, в которой есть ссылка на таблицу nutritionent_list, которая затем ссылается на статическую таблицу с названием и единицами питательных веществ.Второй вариант кажется более гибким, так как мои ожидания неверны, но я даже не знаю, с чего начать написание запросов для сумм и временных рядов.

Спасибо

Ответы [ 2 ]

4 голосов
/ 08 декабря 2011

Вы должны прочитать немного о нормализации базы данных .Большая часть работы по нормализации довольно интуитивна, но на самом деле прохождение определения шагов и просмотр примера помогает понять концепции и очень поможет вам, если вы хотите создать базу данных в будущем.

Что касаетсяДля решения этой проблемы я бы предложил вам использовать 3 таблицы: одну для продуктов (назовем это foods), одну для питательных веществ (nutrients) и одну для конкретных питательных веществ каждого продукта (foods_nutrients).

Таблица продуктов должна иметь уникальный индекс для ссылки и название продукта.Если с продуктом связаны другие данные (может быть, ссылка на изображение или описание), эти данные также должны быть здесь.Каждый отдельный продукт получит строку в этой таблице.

Таблица питательных веществ также должна иметь уникальный индекс для ссылки и название питательного вещества.Каждое из ваших 162 питательных веществ получит строку в этой таблице.

Тогда у вас есть перекрестная таблица, содержащая значения питательных веществ для каждого продукта.Эта таблица имеет три столбца: food_id, nutrient_id и value.Каждый продукт содержит 162 строки в этой таблице, т.е. для каждого питательного вещества.

Таким образом, вы можете добавлять или удалять питательные вещества и продукты по своему усмотрению и запрашивать все, независимо от языка программирования (ну, используя SQL, ноЯ все равно буду использовать это :)).

Давайте попробуем пример.У нас есть 2 продукта в таблице foods и 3 питательных вещества в таблице nutrients:

+------------------+
| 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';
4 голосов
/ 08 декабря 2011

Используйте второй (более нормализованный) подход.

Вы могли бы даже получить меньше таблиц, чем упомянули:

  • tblNutrients
    - NutrientID
    - NutrientName
    - NutrientUOM (единица измерения)
    - Прочие продукты

  • tblFood
    - FoodId
    - FoodName
    - Прочие продукты

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

Поддерживать базу данных с полем 160+ будет кошмаром.

Если в него также включен элемент времени (могут ли измерения изменяться?), То вы можете добавить поле даты к питательному веществу и / или пищевому продукту.таблица в зависимости от того, что может измениться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...