V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
jimisun
V2EX  ›  程序员

Http 协议或(其他)协议的调用换标准 SQL

  •  
  •   jimisun · 257 天前 · 2362 次点击
    这是一个创建于 257 天前的主题,其中的信息可能已经有所发展或是发生改变。

    目前有这样一个需求,适配底层各种数据源,对外提供统一的调用形式


    现在要做一个数据集的功能

    1. 屏蔽底层数据源例如,mysql,oracle,pg 等的底层数据源
    2. 对底层数据源建立字段映射代理,例如源数据表有十个,可以只映射 5 个,外面只能用这 5 个
    3. 对外提供统一的调用形式

    我的思路是将 http 按照指定规范进行调用,后端根据规范将请求使用 querydsl-sql 底层框架生成对应数据库类型的 sql 执行


    提问

    1. 这样实现是否合理
    2. 有没有类似的协议或开源产品能够借用? PS:如果自己开发转换 sql 过程的会有考虑不全,不支持多表等问题
    51 条回复    2023-08-15 09:11:53 +08:00
    dzdh
        1
    dzdh  
       257 天前   ❤️ 1
    GraphQL ?
    NessajCN
        2
    NessajCN  
       257 天前
    你先说清楚「对外提供统一的调用形式」,这个调用形式具体是啥
    http 只是个传输协议,你是要用 restful 接口呢,还是 websocket 发事件呢,还是自己编一套规则,
    还有对外是对哪个「外」,公司内部?第三方开发?平台接入?任意网友?
    jimisun
        3
    jimisun  
    OP
       257 天前
    @dzdh 这个刚才搜索了一下,应该是无具体的数据库无关对吗?
    jimmy3780
        4
    jimmy3780  
       257 天前
    @jimisun GraphQL 不仅跟数据库无关,它甚至都不用关心你的数据是怎么来的
    jimisun
        5
    jimisun  
    OP
       257 天前
    @NessajCN 需求是这样的,底层数据来源会很多,比如接口,csv 文件,oracle 数据库,然后就行提供一个接口调用形式,给内部的大屏,报表,应用,提供一个接口,查询即可。类似市面上的 apijson
    jimisun
        6
    jimisun  
    OP
       257 天前
    @jimmy3780 谢谢,我想您一定很了解这个 GraphQL 。 我向你请教一个重要的我比较关系的问题。GraphQL 支持在运行时添加其实例吗? 比如我从管理系统增加了一条规则,那么就可以使用 GraphQL 訪問。
    NessajCN
        7
    NessajCN  
       257 天前
    @jimisun 那就是最普通的 restful 接口咯....给内部用的就不用考虑验证啊安全这些了直接写接收请求和返回字段就行
    kemistep
        8
    kemistep  
       257 天前
    解决方式很简单:直接传递 sql ,后台解析即可,前端只需要拼接 sql 即可,后台做运算后,传递给前端 json
    jimisun
        9
    jimisun  
    OP
       257 天前
    @jimmy3780 还有一个场景,GraphQL 如果和数据无关的话,怎么实现高性能检索呢? 相比 GraphQL 必须要把数据加载进内存中使用自己的规范进行检索。如果某张表有 1000 万左右能实现吗?
    jimisun
        10
    jimisun  
    OP
       257 天前
    @kemistep 是的,如果这么干的话 领导就该说我什么都没干了。。。
    jimisun
        11
    jimisun  
    OP
       257 天前
    @NessajCN 嗯对,所以就在考虑如何实现兼容底层各种数据源的问题。
    NessajCN
        12
    NessajCN  
       257 天前
    @jimisun 你意思查询者自己不知道数据源,要你在接口里自动判断?还是要遍历?
    jimisun
        13
    jimisun  
    OP
       257 天前
    @NessajCN 例如:有一个数据集管理,有个接口/api 用于访问数据集里面的数据,今天某个数据集记录关联的是 mysql 表,明天可能管理人员修改了配置,改成 oracle 数据库了。但已有的前端调用代码无需修改。这种场景在大数据里库采集转换可能存在。
    NessajCN
        14
    NessajCN  
       257 天前
    @jimisun 那你就把不同数据库用的不同查询语句都放到接口里的不同函数,然后弄个配置文件或者.env 之类的,根据配置调不同的函数。再关照管理人员修改数据库的时候一起把接口的配置也改了呗
    dzdh
        15
    dzdh  
       257 天前
    @jimisun #9

    graphql 就是个 web 应用。一次请求处理一次。

    开发普通 api 接口,不就是你配置文件一改,下次请求就能读到新的数据源了吗?

    同理,graphql 后端也需要你自己写一定的业务逻辑,写的时候支持上实时读取新的配置文件走不同的数据源即可。

    同理,也能支持任意数据源,你再请求个 http 接口请求都行,但是如果是不同数据源的 join 、模糊查询操作,那是数据源本身处理能力的问题,和 graphql 无关
    MineDog
        16
    MineDog  
       257 天前
    听起来是要一个 BI 工具的服务端啊
    cluulzz
        17
    cluulzz  
       257 天前
    prestodb/trino?
    jimisun
        18
    jimisun  
    OP
       257 天前
    @dzdh 1. 所谓的配置文件可以运行时维护吗? 2. graphql 不支持对 avg ,max like 操作吗
    jimisun
        19
    jimisun  
    OP
       257 天前
    @cluulzz 分布式多数据源的 SQL 检索。很棒。但可能对于我的需求存在点问题 1. 工具重 2. 现在要解决的是需要一个协议(或者什么乱七八糟的) 能生成不同数据库的查询语句。
    idealhs
        20
    idealhs  
       257 天前
    GraphQL / OData
    注意 OData 是微软.Net 专属
    nothingistrue
        21
    nothingistrue  
       257 天前
    「底层数据来源会很多,比如接口,csv 文件,oracle 数据库,然后就行提供一个接口调用形式,给内部的大屏,报表,应用,提供一个接口,查询即可」
    「怎么实现高性能检索呢?」
    「如果某张表有 1000 万左右能实现吗?」
    「但可能对于我的需求存在点问题 1. 工具重 」

    综合以上需求,给楼主提供个建议:别在这找了,去找个不要工资的大学实习生吧。
    cluulzz
        22
    cluulzz  
       257 天前
    @jimisun
    1.trino 不算重
    2. 这玩意就是这样用的,只是优化的方向跟常规的 sql 不太一样
    另外如果需要 rbac 的话还是要在业务层做处理
    如果不纠结前端展示问题的话可以看看 metabase,开源版带 rbac,企业版好像带行列权限
    jimisun
        23
    jimisun  
    OP
       257 天前
    jimisun
        24
    jimisun  
    OP
       257 天前
    很感谢大家回复,最后还是想问下大家,有没有类似开源的框架或工具能够生成不同数据库类型的 SQL 语句,感谢。
    udbpl
        25
    udbpl  
       257 天前
    https://gitee.com/freakchicken/db-api.git 可以看下这个,你的需求之前我也搞过
    jimisun
        26
    jimisun  
    OP
       257 天前
    @udbpl 是的很棒,项目中已经落地跟这种功能类似的功能。不能说一模一样也是大差不差,其实现原理都是使用 Mybatis 。 不妨再向上抽象一点,这种新建接口还是需要用户编写 SQL ,能不能用户直接输入个数据库信息就对外提供一个接口呢? 这个接口按照(规范)就可以对这个数据库中的数据进行操作。 我想问大家的问题就是有没有现成的规范能直接转换 SQL 。。。。。。。。。。
    ZGame
        27
    ZGame  
       257 天前
    opemmetadata,这个是数据管道的活。
    dzdh
        28
    dzdh  
       257 天前
    我知道了!

    你需要 phpmyadmin
    yulgang
        29
    yulgang  
       257 天前
    @jimisun #5 Grafana ?
    xudaxian520bsz
        30
    xudaxian520bsz  
       257 天前
    @jimisun 你这个牛逼了,逆开发模式了,之所以放到后端主要还是安全吧,并且后端很多都是自己实现的 tcp 协议。
    swulling
        31
    swulling  
       257 天前
    去年有个项目做了类似的功能。将 DB 转换为动态的 restful API 功能。不过公司代码没法给你分享。

    给你一个类似的项目吧,是 pgsql 的,思路一样。

    https://github.com/PostgREST/postgrest
    jimisun
        32
    jimisun  
    OP
       257 天前
    @xudaxian520bsz nonono 不能说逆开发模式 你仍然可以在此基础上包装你的安全控制逻辑,只不过没提及
    jimisun
        33
    jimisun  
    OP
       257 天前
    @swulling 是的 这很棒,请问下当时你们是用什么技术生成的 SQL 去适配底层各种数据源呢?
    swulling
        34
    swulling  
       257 天前
    @jimisun 写一个 SQL 转译层,我们当时实现了适配 SQLite ,MySQL 和 PostgreSQL 。

    具体代码你可以参考 postgrest 的代码,写的不错。
    RightHand
        35
    RightHand  
       257 天前 via Android
    hibernate+hql ?解析文件写方言?
    jimisun
        36
    jimisun  
    OP
       257 天前
    @swulling 大概看了下 不是 java 写的 就看不明白了。java 中有个套件 querydsl-sql 能生成 SQL 但是没有规范,我想着自己顶一个规范然后生成 SQL 转移层转换即可。你们当时也是自己定的调用规范吗
    jimisun
        37
    jimisun  
    OP
       257 天前
    @RightHand 这个理论上也可行,正准备调研... 不过我个人感觉转移 SQL 比 HQL 有优势。hiber..感觉和数据源强绑定了,没办法做到我生成一个 SQL ,然后通过 RPC 远程到另一个服务执行。。。。
    RightHand
        38
    RightHand  
       257 天前 via Android
    @jimisun SQL 会有兼容问题,远端执行的这个是不是可以参考下数据库 client 相关的实现
    superchijinpeng
        39
    superchijinpeng  
       257 天前
    很多数据库的客户端都支持 HTTP 协议 JDBC 中可以切换,CK 之类的可以参考下
    RightHand
        40
    RightHand  
       257 天前 via Android
    @RightHand 这一套搞下来,不知道有没有意义了。
    yisany
        41
    yisany  
       257 天前
    dataway 吗,试试看能不能满足你的要求
    https://www.dataql.net/docs/dataway/overview
    sofukwird
        42
    sofukwird  
       257 天前 via Android
    不如直接提供 serverless 能力给用户,类似 cloudflare worker
    bringyou
        43
    bringyou  
       257 天前
    如果 op 使用 JVM ,且不排斥 Spring 全家桶的话,可以尝试一下 spring-data-rest 作为接口层,通过它屏蔽后端数据库的区别,配合 spring-data 全家桶使用,比如 spring-data-redis ,spring-data-jpa , spring-data-mongodb, spring-data-elasticsearch
    ourslay
        44
    ourslay  
       257 天前 via iPhone
    superset 的交互可以看看参考下

    实现的话直接使用 JDBC 。定义好接口,获取 schema ,table ,columns 等。不同的 db 去实现一下。
    ikas
        45
    ikas  
       257 天前
    这个提供了对各种数据的统一封装 https://calcite.apache.org/
    然后在做一个 http 上层
    tensorzhang
        46
    tensorzhang  
       257 天前
    https://github.com/Qihoo360/Quicksql/blob/master/docs/zh/index.md

    国内 360 公司 开源的这个 符合你的需求
    jimisun
        47
    jimisun  
    OP
       256 天前
    @tensorzhang 这个很强
    jimisun
        48
    jimisun  
    OP
       256 天前
    @ikas thanks!!!!! 很棒很棒 另请教一下,刚才我检索了一下发现这应该是一个通过标准 SQL-》适配底层各种数据库的一个中间层,那有没有提供标准的请求调用-》生成 SQL 这个过程呢?
    jimisun
        49
    jimisun  
    OP
       256 天前
    @bringyou 是的,加入 Spring 全家桶可以开发更方便,但 spring-data 应该只是个抽象,各种数据库的底层实现还是要自己实现,其实现的过程应该就是我今天想请教大家的问题。
    jimisun
        50
    jimisun  
    OP
       256 天前
    @yisany 可以可以,这些框架都在会简化后端开发努力啊 /笑哭
    zvvvvv
        51
    zvvvvv  
       256 天前
    @ikas calcite 不太行,mysql5.7 和 8 版本许多函数都不支持
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1681 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 39ms · UTC 16:33 · PVG 00:33 · LAX 09:33 · JFK 12:33
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.