Многократный доступ к статическим данным в приложении django - PullRequest
0 голосов
/ 03 декабря 2011

Я создаю приложение, и у меня возникают проблемы с выбором наилучшего способа многократного доступа к статическим данным в приложении 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 (тот, который я сейчас использую):

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

2) СУБД с нормализованными полями:

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

3) СУБД с огурцом:

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

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

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

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

Ответы [ 2 ]

1 голос
/ 03 декабря 2011

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

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

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)
);

Это определенно не , как это должно работать:

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

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

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

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;

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

1 голос
/ 03 декабря 2011

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

...