【问题标题】:Multiple access to static data in a django app在 django 应用程序中多次访问静态数据
【发布时间】:2012-01-11 22:38:52
【问题描述】:

我正在构建一个应用程序,但在选择如何以最佳方式多次访问 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 系统的一些东西:

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

提前致谢, 马里亚诺。

【问题讨论】:

    标签: django json postgresql redis pickle


    【解决方案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 的计算值存储在一个表中,并在基础数据发生变化时自动更新它。最有可能的是,那些很少更改(但仍然可以通过这种方式轻松更新)。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 2015-11-11
        • 2017-12-30
        • 2018-08-04
        • 2011-07-25
        • 1970-01-01
        • 1970-01-01
        • 2011-11-03
        • 2021-08-14
        • 2011-07-20
        相关资源
        最近更新 更多