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

标签 django json postgresql redis pickle

我正在构建一个应用程序,但我无法选择在 Django 应用程序中多次访问静态数据的最佳方式。我在该领域的经验几乎为零,因此我需要一些帮助。

该应用基本上由拖放食物组成。当您将食物拖到确定的位置(例如早餐)时,不同的值会更新:早餐总卡路里、全天营养素(微观/宏观)、全天卡路里……这就是为什么我认为我存储和访问的方式数据是非常重要的性能。

这是我当前使用的 json 文件的摘录:

食物.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:

这是我实际考虑的选项。我可以创建一个食物模型并将营养物质放入 pickle 场。

4) Redis/Django 缓存系统:

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

提前致谢, 马里亚诺。

最佳答案

这是一个关系数据库的典型用例。大多数情况下,或多或少的规范化形式是正确的方法。

根据您的示例,我从头到尾写下了这个数据模型:

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

这绝对不是,它应该如何工作:

every time a food data request is made, the app will hit the db a lot of times to retrieve it.

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

根据上述模型计算一顿饭热量的简单例子:

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

关于django - 在 Django 应用程序中多次访问静态数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8364142/

相关文章:

javascript - 在javascript中附加到json文件

javascript - 使用 $ 作为 JS 对象中的键?

java - 没有适合 postgres 的驱动程序,即使 Class.forName 有效?

python - lambda - 'QuerySet' 对象没有属性 'xxx'

java - 在内存中压缩并序列化一个大的HashMap

python - 如何在django shell中添加多个多对多数据

sql - 使用连接和 "ghost"引用优化 postrgeSQL 查询?

postgresql - 我无法在 Mac Big Sur 上的 MAMP 中添加 pgsql PDO 驱动程序

python - Django 不加载静态 CSS 文件

python - 具有多线程的安全客观多人游戏状态