前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go语言技巧 - 12.【Go实体框架】Facebook开源ent概览

Go语言技巧 - 12.【Go实体框架】Facebook开源ent概览

作者头像
junedayday
发布2022-01-04 13:03:54
1.5K0
发布2022-01-04 13:03:54
举报
文章被收录于专栏:Go编程点滴

go-tip

Ent概览

Simple, yet powerful ORM for modeling and querying data.

Ent作为一款由Facebook开源的库,官方定义为An entity framework for Go。从整个微服务框架来看,它更准确的定位应是 数据模型层的工具库。了解Ent这款企业级工具的大致实现,不仅有助于我们在技术选型时拓宽视野,也能帮助我们能更好地认识数据模型层。

三大特性

Schema As Code

Simple API for modeling any database schema as Go objects.

从定义来看这个特性非常棒 - Ent 可以将各种异构数据库映射到Go语言的结构体。

但在实际的开发中,如果你对各类数据库有深入的理解,就会清楚地知道这个特性在对数据库特性有一定要求时,框架层面就很难满足了。

Easily Traverse Any Graph

Run queries, aggregations and traverse any graph structure easily.

强调对图结构的 查询、聚合和遍历。这里的图数据库和传统的关系型数据库差别不小,有兴趣的朋友可搜索图数据库的相关概念。

Statically Typed And Explicit API

100% statically typed and explicit API using code generation.

利用代码生成的能力,保证静态类型和显示声明的API。

特性总结

三大特性,分别从 支持的数据库能力集针对图形数据处理能力代码生成的输出形式,描述了Ent框架的优点。

这里,我会更聚焦于第二点中的关键词:图形数据。让我们带着对三个特性的初印象,开始了解相关官方示例。

Ent实践

Ent工具的使用方式并不是本篇的重点,具体的操作方法我会放在链接里,文中只给出关键性的内容

1.创建实体

链接 - https://entgo.io/docs/getting-started/#create-your-first-entity

代码语言:javascript
复制
u, err := client.User.
        Create().
        SetAge(30).
        SetName("a8m").
        Save(ctx)

代码和GORM非常类似,但不支持复杂结构体的传入,面对大量参数时比较麻烦。

2.查询实体

链接 - https://entgo.io/docs/getting-started/#query-your-entities

代码语言:javascript
复制
u, err := client.User.
        Query().
        Where(user.Name("a8m")).
        // `Only` fails if no user found,
        // or more than 1 user returned.
        Only(ctx)

基本同上,表达方式还是很明确的。但对于Only这种新引入的关键词,对新人来说有学习成本。

3.Edge相关

  • https://entgo.io/docs/getting-started/#add-your-first-edge-relation
  • https://entgo.io/docs/getting-started/#add-your-first-inverse-edge-backref
  • https://entgo.io/docs/getting-started/#create-your-second-edge

我们以一个复杂Edge为例:

代码语言:javascript
复制
cars, err := client.Group.
        Query().
        Where(group.Name("GitHub")). // (Group(Name=GitHub),)
        QueryUsers().                // (User(Name=Ariel, Age=30),)
        QueryCars().                 // (Car(Model=Tesla, RegisteredAt=<Time>), Car(Model=Mazda, RegisteredAt=<Time>),)
        All(ctx)

从表达式上来看,就是查询Group、然后关联查询User、最后再查到Car。

首先,我们要认识到 - 抛开背后的实现,这种表达方式很简洁

如果底层是MySQL,这里至少关联了三张实体表(JOIN),很容易引起性能问题。这个问题也就是上面所说的,框架屏蔽了异构数据库而导致的。

参考资料

Github - https://github.com/ent/ent

官网 - https://entgo.io/

思考

通过相关资料和简单实操,我对于Ent框架的定位是 - 一个面向图数据库的ORM框架。相信随着图数据库的逐渐成熟,Ent会更具价值。但考虑到以下两点:

  1. 图数据库的成熟周期还需要一段时间,当前的维护成本高;
  2. 在非图数据库上使用Ent,对开发者的要求很高,既要了解Ent对不同数据库的底层实现,又要懂数据库原理。

举个例子,ent的部分Edge特性需要依赖数据库的外键,但如今主流数据库的实践,倡导去外键,而是将相关逻辑转移到程序代码里。

所以,我不建议将Ent引入到项目中。关于Ent更多的细节需要大家自行阅读和实践。

这里,我抛出一个自己的理解:从编程语言框架层面,不应过度基础设施的复杂度。从异构数据库来说,它们的特性、维护方式、设计模式都各不相同,应寻找每种数据库对应的工具库,而不应期望毕其功于一役。

换一句话,如果期望一个工具库能适配十种数据库,那么换一种角度,这十种数据库更应该被封装成一种数据库。通用性如果能沉淀在基础设施上,价值远大于在工具库上做适配。

小结

Ent能在Facebook等公司与Kratos框架上沉淀,证明了它具备实际工程落地的能力,但对使用者的要求很高,很难具备普适性。

前文为了表达个人想法,我在论述观点时会相对态度鲜明,但并非对Ent持有否定态度。相反地,从具体的实现细节来看,Ent给了我不少启发,尤其是强调静态类型,能看出它对性能的追求。

Github: https://github.com/Junedayday/code_reading Blog: http://junes.tech/ Bilibili: https://space.bilibili.com/293775192

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-01-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Go编程点滴 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Ent概览
  • 三大特性
    • Schema As Code
      • Easily Traverse Any Graph
        • Statically Typed And Explicit API
          • 特性总结
          • Ent实践
            • 1.创建实体
              • 2.查询实体
                • 3.Edge相关
                • 参考资料
                • 思考
                • 小结
                相关产品与服务
                数据库
                云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档