在django应用程序中多次访问静态数据

时间:2011-12-02 23:49:55

标签: django json postgresql redis pickle

我正在构建一个应用程序,我无法选择在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函数来访问食物数据,然后更新相应的值。这个文件大小为2mb,但随着我添加更多食物肯定会增加。我正在使用此选项,因为它是开始构建应用程序最快的选项,但我不认为它是实时应用程序的不错选择。

2)具有规范化字段的RDBMS:

我可以创造两种模式:食物和营养素,每种食物都含有40多种与FK相关的营养素。我看到的问题是,每次发出食物数据请求时,应用程序都会多次点击数据库进行检索。

3)带有picklefield的RDBMS:

这是我正在考虑的选项。我可以创建一个食物模型,并将营养物质放入泡菜田。

4)使用Redis / Django Cache系统的东西:

我会更深入地研究这个选项。我已经阅读了一些有关它们的内容,但我不清楚是否有某种方法可以用它们来解决我的问题。

提前致谢, 马里亚诺。

2 个答案:

答案 0 :(得分:1)

我认为您使用的平面文件版本排在最后。每次请求时,都是从上到下阅读。对于这个尺寸,我认为这是最后的地方。缓存系统将提供最佳性能,但RDBMS最容易管理/扩展,而且您的查询将自动缓存。

答案 1 :(得分: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)
);

这肯定是,它应该如何运作:

  

每次发出食物数据请求时,应用程序都会点击数据库   检索它的时间。

您应该在视图或函数中计算/聚合所需的所有值,并且每次请求只打一次数据库,而不是多次。

根据上述模型计算膳食卡路里的简单例子:

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的计算值,并在基础数据发生更改时自动更新。最有可能的是,那些很少改变(但仍然很容易以这种方式更新)。