我正在构建一个应用程序,我无法选择在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系统的东西:
我会更深入地研究这个选项。我已经阅读了一些有关它们的内容,但我不清楚是否有某种方法可以用它们来解决我的问题。
提前致谢, 马里亚诺。
答案 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
的计算值,并在基础数据发生更改时自动更新。最有可能的是,那些很少改变(但仍然很容易以这种方式更新)。