06|get hands dirty:SQL查询工具怎么一鱼多吃?
该思维导图由 AI 生成,仅供参考
SQL
- 深入了解
- 翻译
- 解释
- 总结
本文介绍了如何使用Rust语言设计一个可以对任何数据源使用SQL查询的库。作者首先提到了在实际工作中经常需要与各种数据源打交道,而使用SQL进行数据获取、过滤、投影和排序的过程。然后,作者介绍了设计分析的过程,包括SQL解析器的编写、数据加载为DataFrame的操作以及如何将SQL AST转换为DataFrame AST。最后,作者提到了宏编程在这个过程中的应用,以及Rust语言优秀的模式匹配支持。整体而言,本文涵盖了SQL查询工具的设计和实现过程,展示了Rust语言在此领域的应用和特点。 文章通过示例代码展示了如何创建一个自定义的SQL方言,支持从URL中读取数据,并且通过trait的方式实现了这一功能。这种灵活的特性在Rust开发中很常见,展示了Rust语言的强大之处。 在实现AST的转换过程中,作者通过模式匹配和数据结构转换的方式,展示了Rust语言对于复杂数据处理的优雅支持。同时,通过引入trait和async/await特性,作者展示了如何构建低耦合、高内聚的代码结构,使得未来对于代码的修改和扩展变得更加容易。 总的来说,本文通过深入的技术讲解和实际示例,展示了Rust语言在数据处理和库设计方面的优势,对于想要深入了解Rust语言在数据处理领域应用的读者具有很高的参考价值。
《陈天 · Rust 编程第一课》,新⼈⾸单¥68
全部留言(68)
- 最新
- 精选
- leesper置顶陈天老师,学完了这节课程,我觉得你和陈皓老师给了我新的启发。 在陈皓老师的《左耳听风》的《编程的本质》一节,提到了这么两个公式 (1)程序=算法+数据结构 (2)算法=逻辑+控制 我从这两个公式中领悟出:“程序=逻辑抽象+数据结构+控制”。数据结构是业务逻辑的静态的描述,它用术语表示数据结构的定义,而逻辑抽象是动态的,是对业务流程的抽象。 您在课程里所说的“绝大多数处理逻辑都是把数据从一个接口转换成另一个接口。”、“好的代码,应该是每个主流程都清晰简约,代码恰到好处地出现在那里,让人不需要注释也能明白作者在写什么” 与陈皓老师的“有效地分离 Logic、Control 和 Data 是写出好程序的关键所在!”,其实表达的是同一个意思。写任何代码,设计好Logic和Data,业务流程就算完成了(功能性需求),然后在这个基础上不断地优化Control,就能提高代码性能(非功能性需求)。 以“高性能网络编程”为例,网络编程的业务逻辑是“客户机-服务器模型”: (1)客户进程发送请求 (2)服务进程处理请求(可能会访问某些本地或远程资源) (3)服务进程发送响应 (4)客户进程处理响应 在这个过程中所体现的就是您所说的“绝大多数处理逻辑都是把数据从一个接口转换成另一个接口”的过程: (1)客户进程中的业务数据变成请求数据包 (2)请求数据包编码成字节流发送到网络上 (3)服务进程获得字节流把它解码成请求数据包 (4)服务进程根据请求数据包访问资源得到结果 (5)客户进程把结果数据变成响应数据包 (6)响应数据包编码成字节流发送到网络上 (7)客户进程获得字节流把它解码成响应数据包 (8)客户进程处理响应数据包 对于一个最简单的iterative echo server来说,一次服务一个客户端,字节码解码成字符串,业务逻辑就是把客户端发来的再原封不动编码成字节码发回去就可以了。 然而对于一个有着复杂业务逻辑的高性能服务器来说,要考虑的点就不一样了: (1)要实现字节码和“自定义消息”之间的来回转换,就要自定义Codec,甚至要引入protobuffer/flatbuffer,并实现消息的注册机制 (2)要一次服务多个客户端,就要引入epoll/kqueue这样的IO multiplexing机制,实现单个线程监听多个socket fd,甚至one-loop-per-thread,并做好网络连接管理,关闭服务器的时候不能硬着陆,要优雅关闭:等待所有网络连接接收并处理完消息再退出 (3)要提高IO性能,就要引入nonblocking IO (4)要避免复杂业务逻辑占用IO线程资源,就要引入工作者线程池,把服务端对消息的处理放到另一个线程中执行,并做好IO线程和工作者线程的同步 (5)如果服务端要访问远程资源,就要引入配置,在服务启动时装配好各种mysql或者redis的handle,甚至自己实现一个connector访问其他的服务 这些都是属于Control范畴要考虑的东西。Logic决定了程序复杂度的下限,Control决定了上限。把Logic和Control混在一起,往往是写出来的代码难以维护的原因。
作者回复: 说得非常好! 对于「有着复杂业务逻辑的高性能服务器」,除了你说的这些,还有在处理的整个 pipeline 中要考虑引入 hook 做事件通知,以满足日志,监控等需求。在第 21 讲我们讨论 KV server 的时候,会逐步把你说的这些点都体现到。
2021-09-2030 - 葡萄置顶老师的课程消除了对解决这类问题(自己实现一个解析器的扩展)的恐惧,或者说以前一直在使用高级封装的语言,对这些偏低层一点的东西总是不敢触碰,一点点分析下来,完全没有想象中的那么难。哈哈,这就是get hands dirty的精要吧。学习rust很好,听老师讲课更好,感谢老师。
作者回复: 👍
2021-09-03219 - pedro置顶In [1]: import queryer_py In [2]: sql = queryer_py.example_sql() In [3]: print(queryer_py.query(sql, 'csv')) name,total_cases,new_cases,total_deaths,new_deaths European Union,36489548.0,84973.0,766627.0,541.0 India,32857937.0,47092.0,439529.0,509.0 South America,36922209.0,37641.0,1131322.0,1104.0 Iran,5025233.0,33170.0,108393.0,599.0 Africa,7821187.0,30793.0,196917.0,639.0 Brazil,20804215.0,27345.0,581150.0,737.0 本周最骄傲、最爽的demo: ```shell $ tree . . ├── httpie │ ├── src │ └── target ├── queryer_all │ ├── queryer │ ├── queryer-py │ └── target ├── scrape_url │ ├── src │ └── target ├── thumbor │ ├── src │ └── target ```
作者回复: 👍 全都跟下来啦。可以试着写写 nodejs 的支持。如果有疑问,可以去 github repo 里找答案 :)
2021-09-037 - Fenix太赞了,这种教学模式,处理问题的思路很有启发
作者回复: 👍 希望能够帮到
2021-09-0314 - Geek_01c6d8全网最好的rust课程,没有之一!!!
作者回复: 谢谢抬爱!
2021-09-249 - bearlu老师如何有效阅读docs.rs,我看你引入来的crate的文档,但是不知道如何有效学习?
作者回复: 我就是在需要的时候查阅,并不会系统地去一篇篇读。对于要了解的数据结构,我会去看它都实现了哪些 trait。未来你会逐渐明白这非常重要。有时候甚至被数据结构自己提供了哪些功能更重要。
2021-09-046 - Colt老师的思路非常正,这几次实践课可以看出RUST的魅力和优雅,能力有限需要多品几次
作者回复: 谢谢赞赏!
2021-09-105 - 老荀太强了!这种实战性质的教学正是大家都需要的!不是那种重复啰嗦语法细节的烂课程
作者回复: 谢谢!这周先给大家看看 Rust 能做什么,怎么做。下周起就要从堆和栈的关系入手讲所有权啦。
2021-09-035 - 拉斯特通过一个实际案例展现了rust的特性,设计模式的使用,决解问题的思路和设计过程。简直不要太棒~
作者回复: 谢谢夸奖!希望能够帮到。
2021-09-035 - 玄澈老师你好,有观点认为用 Deref 模拟继承通常不是好的做法。例如:https://www.zhihu.com/question/36488041 https://rust-unofficial.github.io/patterns/anti_patterns/deref.html 有好处也有坏处,我们该如何权衡以至于防止滥用呢。
作者回复: 首先 deref 的用途不是模拟继承。它最根源的需求是为只能指针提供对内部数据的方便的访问:https://doc.rust-lang.org/std/ops/trait.Deref.html。当你需要你的数据结构在使用时用起来可以感觉和内部的数据类似时,可以使用 Deref trait。比如我可以构建一个 Memmap 结构,把文件 mmap 到内存中,但如果我提供一系列额外的接口,会让使用者很不方便,但我把它 deref 到 &[u8],让用户操作起来像一个内存 buffer,用起来就很舒服。当然,滥用它会给使用者带来一些困惑,所以标准文档建议只有在构建智能指针时使用。 我的建议: 1. 简单的数据结构的封装。像我 DataSet 的使用那样。 2. 智能指针。比如你要实现一个 SmartString,在 < 24 字节时使用栈上的内存,更大的字符串才使用 String。这样的场合,如果不用 Deref,使用起来会非常不友好。
2021-09-054