当前位置: 首页 > 面试题库 >

Haskell持久加入Esqueleto

巢星纬
2023-03-14
问题内容

我一直在研究与SQL数据库接口的Persistent库。假设我有一个包含配方,配方,成分和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)

这将返回(Recipe,RecIng,Ingredient)的元组。

我真正想要的是一种查询配方的方法,其结果如下:

data Recipe = Recipe { title :: String
                     , ingredients :: [Ingredient]
                     }

data Ingredient = Ingredient { name :: String
                             , quantity :: Integer
                             }

除了定义一组额外的数据类型并转换元组之外,是否有进行此类操作的最佳实践?


问题答案:

+1对亚当的评论,这是IMO的正确答案。

可以
采用的另一种方法是使用嵌入式实体,这实际上意味着将JSON编码成每个配方中的成分列表。但这将是不好的SQL设计,将导致表锁定问题以进行更新,并且无法很好地扩展大量成分。

换句话说,您要使用的Haskell表示形式与将数据存储在数据库中的正确方法之间不匹配。这并不意味着您的数据库格式或Haskell数据类型都存在问题:这是逻辑上的区别。应对这种差距的正确方法是拥有两种数据类型,以及在两种数据类型之间进行转换的明智方式。



 类似资料:
  • 我希望在每次加载或持久化实体时包装/展开它。我知道我不能使用JPA监听器来完成这件事,因为它们只能对对象执行一个操作,而不能与其他对象交换它。自然的解决方案是使用方面。但是有没有特别的方法我可以切入呢?问题是要包装/解包装的实体可以是另一个实体的字段...

  • 本文向大家介绍Redis持久化深入详解,包括了Redis持久化深入详解的使用技巧和注意事项,需要的朋友参考一下 1、概述 Redis 是内存数据库,如果不能将内存中的数据保存到磁盘中,那么一旦服务器进程退出,服务器的数据库数据也会消失,所以Redis提供了持久化的功能,redis分为两种持久化方式:RDB和AOF。有以下几个特点: 1.RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储。

  • JPA 3.0于2020年11月发布,我想大多数JPA提供商(Hibernate、EclipseLink、OpenJPA)仍然支持JPA 2.2。是否有迁移到新版本的计划?这将不是那么简单,因为,例如,顶级包已经更改(javax.persistence-

  • Akka持久化使有状态的actor能留存其内部状态,以便在因JVM崩溃、监管者引起,或在集群中迁移导致的actor启动、重启时恢复它。Akka持久化背后的关键概念是持久化的只是一个actor的内部状态的的变化,而不是直接持久化其当前状态 (除了可选的快照)。这些更改永远只能被附加到存储,没什么是可变的,这使得高事务处理率和高效复制成为可能。有状态actor通过重放保存的变化来恢复,从而使它们可以重

  • 我正在使用网络逻辑10.3。我正在尝试配置一个持久订阅,其中包含由 jdbc 存储(在 Oracle DB 中)支持的持久消息。我有一个主题,MDB 正在作为持久订阅者侦听该主题。在场景-1下:如果我发送消息,它会命中MDB。 在场景2中:我挂起了MDB,希望发送到主题的消息只要不被MDB(它是唯一注册的持久订阅者)使用,就会一直存在。但是当我向主题发送消息时,它短暂地出现在那里,然后就消失了(我

  • 问题内容: 我有一个托管bean,其中包含当前页面的实体对象列表。在我创建一个新对象并在事务中使用persist()将其持久保存到数据库之后;在另一个事务中,当我调用merge时(由于该实体由于先前的事务提交而处于分离状态);实体管理器无法在持久性上下文中找到对象,并向数据库抛出选择查询。我是否缺少某些东西,或者是正常行为? 更新:当我使用mysql数据库和自动生成的ID列时,存在上述问题。当我在