2011-12-02 1 views
0

Я создаю приложение, и у меня возникли проблемы с выбором того, как наилучшим образом получить доступ к статическим данным в приложении django. Мой опыт в области близок к нулю, поэтому я могу воспользоваться некоторой помощью.Множественный доступ к статическим данным в приложении django

Приложение в основном состоит из перетаскивания & Капля продуктов. Когда вы перетаскиваете пищу в определенное место (например, завтрак), различные значения обновляются: общий калорийность завтрака, общее количество питательных веществ в день (микро/макро), общее количество калорий в день ... Вот почему я думаю, что я храню и получаю доступ к данных, это довольно важная работа.

Это отрывок из файла JSON я в настоящее время с помощью:

foods.json

{ 
"112": { 
    "type": "Vegetables", 
    "description": "Mushrooms", 
    "nutrients": { 
     "Niacin": { 
      "unit": "mg", 
      "group": "Vitamins", 
      "value": 3.79 
     }, 
     "Lysine": { 
      "units": "g", 
      "group": "Amino Acids", 
      "value": 0.123 
     }, 
     ... (+40 nutrients) 
    "amount": 1, 
    "unit": "cup whole", 
    "grams": 87.0 } 
} 

Я думал о различных вариантах:

1) в формате JSON (Один В настоящее время я использую):

Каждый раз, когда я перетаскиваю пищу в «droppable» место, я вызываю функцию getJSON для доступа к данным о еде, а затем обновляю соответствующие значения. Этот файл имеет размер 2 МБ, но он, безусловно, будет увеличиваться по мере того, как я добавляю к нему больше продуктов. Я использую этот параметр, потому что это самое быстрое начало для создания приложения, но я не думаю, что это хороший выбор для живого приложения.

2) RDBMS с нормированными полями:

я мог бы создать две модели: Продукты питания и питательных веществ, каждая пища имеет 40+ питательные вещества, связанные с помощью FK. Проблема, которую я вижу в этом, заключается в том, что каждый раз, когда делается запрос данных о питании, приложение будет ударять db много раз, чтобы получить его.

3) RDBMS с picklefield:

Это вариант Я действительно рассматривает. Я мог бы создать модели продуктов питания и поместить питательные вещества в марихуану.

4) Что-то с системой Redis/Django Cache:

Я нырнуть глубже в этот вариант. Я прочитал кое-что о них, но я не знаю, есть ли способ использовать их для решения проблемы, которая у меня есть.

Заранее спасибо, Мариано.

ответ

1

Это типовой пример использования для реляционной базы данных . Более или менее нормализованная форма является правильным способом большую часть времени.

Я написал эту модельданных вверх от верхней части головы, по вашему примеру:

CREATE TABLE unit(
unit_id integer PRIMARY KEY 
,unit text NOT NULL 
,metric_unit text NOT NULL 
,atomic_amount numeric NOT NULL 
); 

CREATE TABLE food_type(
food_type_id integer PRIMARY KEY 
,food_type text NOT NULL 
); 

CREATE TABLE nutrient_type(
nutrient_type_id integer PRIMARY KEY 
,nutrient_type text NOT NULL 
); 

CREATE TABLE food(
food_id serial PRIMARY KEY 
,food text NOT NULL 
,food_type_id integer REFERENCES food_type(food_type_id) ON UPDATE CASCADE 
,unit_id integer REFERENCES unit(unit_id) ON UPDATE CASCADE 
,base_amount numeric NOT NULL DEFAULT 1 
); 

CREATE TABLE nutrient(
nutrient_id serial PRIMARY KEY 
,nutrient text NOT NULL 
,metric_unit text NOT NULL 
,base_amount numeric NOT NULL 
,calories integer NOT NULL DEFAULT 0 
); 

CREATE TABLE food_nutrient(
food_id integer references food (food_id) ON UPDATE CASCADE ON DELETE CASCADE 
,nutrient_id integer references nutrient (nutrient_id) ON UPDATE CASCADE 
,amount numeric NOT NULL DEFAULT 1 
,CONSTRAINT food_nutrient_pkey PRIMARY KEY (food_id, nutrient_id) 
); 

CREATE TABLE meal(
meal_id serial PRIMARY KEY 
,meal text NOT NULL 
); 

CREATE TABLE meal_food(
meal_id integer references meal(meal_id) ON UPDATE CASCADE ON DELETE CASCADE 
,food_id integer references food (food_id) ON UPDATE CASCADE 
,amount numeric NOT NULL DEFAULT 1 
,CONSTRAINT meal_food_pkey PRIMARY KEY (meal_id, food_id) 
); 

Это, безусловно, не, как он должен работать:

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

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

Простой пример для расчета калорий пищи в соответствии с приведенной выше модели:

SELECT sum(n.calories * fn.amount * f.base_amount * u.atomic_amount * mf.amount) 
                   AS meal_calories 
FROM meal_food mf 
JOIN food f USING (food_id) 
JOIN unit u USING (unit_id) 
JOIN food_nutrient fn USING (food_id) 
JOIN nutrient n USING (nutrient_id) 
WHERE mf.meal_id = 7; 

Вы также можете использовать materialized views. Например, сохраните вычисленные значения за food в таблице и обновите их автоматически, если базовые данные изменятся. Скорее всего, они редко меняются (но все еще легко обновляются таким образом).

1

Я думаю, что версия с плоским файлом, которую вы используете, приходит на последнее место. Каждый раз, когда он запрашивается, его читают сверху вниз. По размеру я думаю, что это на последнем месте. Система кэширования обеспечит лучшую производительность, но RDBMS будет проще всего управлять/расширять, а ваши запросы будут автоматически кэшироваться.