postgresql 如何优化膳食计划应用程序的DB模式?

ryoqjall  于 2023-06-22  发布在  PostgreSQL
关注(0)|答案(2)|浏览(117)

我正在为一个膳食计划应用程序设计一个DB模式。每个膳食计划包括块(2个月的饮食,2个月的膨胀),每天的每一餐,每天的每一餐的食物。
我做了一个规范化的数据库模式,但是如果我想获取一个完整的膳食计划与它的分析,查询将通过超过6个不同的表,这可能会真正减缓应用程序在未来。但我看不出有什么不同的方法。要获得整个膳食计划,它必须通过MealProgram> MealProgramBlock> DayMeal> DayMealFood> FoodOnDayMealFood> Food> FoodNutrient> Nutrient
我知道NoSQL解决方案可能适合这个用例,但如果我需要更新特定的营养素或食物,那就不行了,我不想更新所有现有的记录。

Table User {
  id varchar [primary key]
}

Table Food {
  id varchar [primary key]
  name String
}

Table FoodNutrient {
  foodId varchar [ref: > Food.id]
  nutrientId varchar [ref: > Nutrient.id]
  amount integer
}

Table Nutrient {
  id varchar [primary key]
  name varchar
  unitName String
}

Table MealProgram {
  id varchar [primary key]
  name varchar
  authorId varchar [ref: > User.id]
  customerId varchar [ref: > User.id]
}

Table MealProgramBlock {
  id varchar [primary key]
  name varchar
  programId varchar [ref: > MealProgram.id]
}

Table DayMeal {
  id varchar [primary key]
  blockId varchar [ref: > MealProgramBlock.id]
  name varchar
  day integer
  time varchar
}

Table DayMealFood {
  id varchar [primary key]
  dayMealId varchar [ref: > DayMeal.id]
}

Table FoodOnDayMealFood {
  id varchar [primary key]
  dayMealFoodId varchar [ref: > DayMealFood.id]
  foodId varchar [ref: > Food.id]
  weight integer
  unit varchar
}

yiytaume

yiytaume1#

所使用的数据模型在很大程度上取决于托管该数据的数据库解决方案的类型。在你的情况下,它的Postgres和这些建议是有针对性的。如果数据库是像Teradata一样的MPP数据库,那就完全不同了。话虽如此,这里有一些指针。可以抓住任何将为你工作的。

  • DayMealFoodFoodOnDayMealFood表合并为一个Meal表。这将允许您在一个地方存储关于一顿饭的所有信息,并减少获取一顿饭计划时需要执行的连接次数。
  • meal_type列添加到“膳食”表。这将允许您区分不同类型的膳食,如早餐、午餐、晚餐和小吃。该信息可用于生成关于用户用餐模式的报告和见解。
  • meal_plan_id列添加到Meal table中。这将允许您将膳食与膳食计划相关联,并且将更容易获取特定膳食计划中的所有膳食。
  • created_atupdated_at列添加到数据模型中的所有表。这将允许您跟踪数据随时间的变化
  • DayMealFood tablecomposite primary key。单个id值对于查询表不是很有用,例如:要找到包含特定食物的所有膳食,需要加入DayMealFood Table & Food Table。composite primary keydayMealIdfoodId列)允许您按日餐或食物查询表,而不必连接两个表。
  • materialized view用于MealPlancaching频繁使用的数据提高性能当用户请求膳食计划时,应用程序可以首先检查膳食计划是否在materialized view中。如果膳食计划在示例化视图中,应用程序可以简单地从示例化视图返回数据
  • 使用caching layer存储DayMealFood表中的数据。这将允许应用程序从缓存层而不是数据库获取数据。当用户请求膳食计划时,这将显著提高应用程序的性能
omvjsjqw

omvjsjqw2#

从您在聊天中的评论中,我们看到您正在使用Prisma。不幸的是,Prisma还不做JOIN。因此,它实际上在规范化的表上执行多个SQL查询,其中单个查询中的一堆JOIN通常根本不会成为性能问题-它们实际上是SQL数据库的基础。
所以,技术的选择是罪魁祸首。标签:https://github.com/prisma/prisma/issues/5184
如果你找不到适合你的替代技术,你必须使用Prisma,反规范化可能是一种方法。
在RDBMS的世界中,为nutrientfood的更改更新多个记录可能会感觉不对,但一种甚至无法进行JOIN的技术也是如此。
另一种办法是:
选择另一个能够执行JOIN的ORM(如果您确实需要的话),如sequelizeknex
更激进的替代方案可能是:
选择一个定义DDL(数据库模式)和运行迁移的工具,比如flyway,然后使用pg客户端库编写SQL语句。

相关问题