我一直在查看持久库,以便与sql数据库进行接口。假设我有一个包含菜谱的数据库,其中包含食谱、配料和RecIng表。
我对持久性的理解(诚然是有限的)使我相信我应该定义这样的表格:
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Recipe
title String
Ingredient
name String
RecIng
recId RecipeId
ingId IngredientId
quantity Int
|]这样,就可以使用Esqueleto获得这些表之间的内部连接:
select $
from $ \(i `InnerJoin ` ri `InnerJoin` r) -> do
on (r ^. RecipeId ==. ri ^. RecIngIngId)
on (i ^. IngredientId ==. ri ^. RegIngRecId)
return (r, ri, i)这还包括(配方,RecIng,成分)的元组。
我真正想要的是一种查询食谱的方法,结果如下:
data Recipe = Recipe { title :: String
, ingredients :: [Ingredient]
}
data Ingredient = Ingredient { name :: String
, quantity :: Integer
}除了定义一组额外的数据类型和转换元组之外,还有做这种事情的最佳实践吗?
发布于 2014-02-11 08:03:45
+1对亚当的评论,这是正确的答案,海事组织。
您可以采取的另一种方法是使用嵌入式实体,这实际上意味着JSON-将成分列表编码到每个菜谱中。但是,这将是糟糕的SQL设计,会导致更新中的表锁定问题,并且不会对大量的成分进行很好的扩展。
换句话说,您想要使用的Haskell表示与将数据存储在数据库中的正确方法不匹配。这并不意味着数据库格式或Haskell数据类型都有问题:这是一个逻辑上的区别。对这一差距的正确反应是有两种数据类型和一种智能的方式在它们之间进行转换。
https://stackoverflow.com/questions/21686579
复制相似问题