为 postgres 映射一组记录

Posted

技术标签:

【中文标题】为 postgres 映射一组记录【英文标题】:slick mapping an array of records for postgres 【发布时间】:2013-11-26 19:17:08 【问题描述】:

有人可以通过向我展示如何映射这两种类型来帮助我吗:

case class forumQuote(
            index:          Int,
            startOffset:    Int,
            endOffset:      Int,
            isDirect:       Boolean,
            quotedId:       Int)
case class forumQuotes(quotes: List[forumQuote])

在postgres中表示为:

CREATE TYPE forum_quote AS
(
    index           INTEGER,
    q_start_offset  INTEGER,
    q_end_offset    INTEGER,
    is_direct       BOOLEAN,
    quoted_id       INTEGER
);

中用作数组字段
CREATE TABLE forum_posts
(
...
quotes      forum_quote [],
...
)

在我自己的升降桌中用作:

object ForumPosts extends Table[...] 
...
def quotes = Column[forumQuotes]("forum_quotes")
...

注意:我不希望看到任何 JDBC 数组的使用,因为稍后我需要用 hstore 做一些时髦的东西 (Key[String] => Value[Array[T]]),其中 T 是一个 postgresql 记录。

【问题讨论】:

这似乎是一个非常奇怪的数据设计——这是一个非常丰富的数据结构,可以存储在单个列中。拥有一个带有指向forum_posts 的外键的forum_quotes 表(因为这是一对多的关系)然后让您的ORM 为您遍历它不是更有意义吗? 太慢了。我有几个原始数据(大约 20 个,没有索引)。稍后我将构建自定义倒排搜索索引,我主要是学习如何为此目的进行操作。 我不知道您正在使用的技术,但我想知道是否有其他方法可以解决实际的潜在问题,而不需要这种非标准/不寻常的功能:a " NoSQL”文档存储?一种延迟加载方法来获取您检索到的帖子的引号(我认为您永远不会以相反的方式加载,否则这种结构真的没有意义)?比 ORM 生成的更能利用索引的自定义 SQL? postgres 完全有能力做这种“非标准”的东西。作为 gist/gin 索引结构的证明。数据透视是您获得 nosql 优势的方式。如果您永远不需要在数据 A 的隔离中访问数据 B,并且它是一对多的关系,那么只有旋转它才有意义。有问题的数据不需要在索引中。然而,在我的工作中,hstore/gin 的性能比传统索引要好。我正在移植现有的代码,在我转移到 hstore 的东西之前,我想尝试一些更简单的东西。否则我会成为一种关系。 【参考方案1】:

仅供参考,slick-pg 很快就会全面支持记录和数组。


我改编了来自 slick dudes 的 postgres 扩展插件的代码。下面显示了如何获取记录的类型映射器和记录数组。

  object ForumQuoteMapper extends RecordMapper[ForumQuote] 
    val name = "forum_quote"
    val extractorRegex = "\\((\\d+),(\\d+),(\\d+),([t|f]),(\\d+)\\)".r
    def fnFromString = (lit: String) =>  
      def toBool(str: String) =  str match  case "t" => true; case "f" => false

      lit match 
        case extractorRegex(index,startOffset,endOffset,bol,quotedId) =>
          ForumQuote(index.toInt,startOffset.toInt,endOffset.toInt,toBool(bol),quotedId.toInt)
      
    def fnToString = (v: ForumQuote)=>s"($v.index, $v.startOffset, $v.endOffset, $v.isDirect,$v.quotedId)"
  
  implicit val forumQuoteRecordMapper = ForumQuoteMapper.getRecordMapper
  implicit val forumQuoteArrayMapper = ForumQuoteMapper.getRecordArrayMapper

修改后的代码可以在here找到。一旦我开始将它集成到我的代码中,我可能会发现并修复大量错误:D 但它按原样通过了基本测试用例。

【讨论】:

以上是关于为 postgres 映射一组记录的主要内容,如果未能解决你的问题,请参考以下文章

使用一个查询递增具有唯一约束的字段中的一组值,Postgres

Grafana 引用数据集变量以使用 Postgres 驱动程序转换图例值

Postgres 选择从昨天开始存储为纪元的记录

什么 Postgres 类型将映射到休眠中 Float 类型的列?

Postgres - 如何返回缺失数据计数为 0 的行?

在 Postgres 中将多列合并为一列