我正在构建一个应用程序,但我无法选择在 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/