到目前为止,我们仅靠代码就解决了词频问题。 本周,我们将在基础架构的帮助下解决该问题。 面对我们的特定问题,还有什么比关系数据库更适合?
这是《编程风格练习》焦点系列的第 14 个帖子。其他帖子包括:
- 以编程风格介绍练习
- 以编程风格进行练习,将内容堆叠起来
- 编程风格的练习,Kwisatz Haderach风格
- 编程风格的练习,递归
- 具有高阶功能的编程风格的练习
- 以编程风格进行练习
- 以编程风格进行练习,回到面向对象的编程
- 编程风格的练习:地图也是对象
- 编程风格的练习:事件驱动的编程
- 编程风格的练习和事件总线
- 反思编程风格的练习
- 面向方面的编程风格的练习
- 编程风格的练习:FP&I / O
- 关系数据库风格的练习 (本文)
- 编程风格的练习:电子表格
- 并发编程风格的练习
- 编程风格的练习:在线程之间共享数据
- 使用Hazelcast以编程风格进行练习
- MapReduce样式的练习
- 编程风格的练习总结
我们可以通过以下方式解决该问题:加载从数据库中的文件读取的数据,并使用相关查询检索前25个单词。 在SQL中,此查询将简单地转换为以下内容:
SELECTvalue,COUNT(*)ascount
FROMwords
GROUPBYvalue
ORDERBYcountDESC
LIMIT25;
Python或Kotlin都原生提供低级数据库访问API。 但是,它们都不是很有趣,因为它只是连接到数据库,然后发送SQL字符串进行查询。 取而代之的是,让我们趁此机会使用Kotlin SQL Framework Exposed :
公开的是通过JDBC驱动程序为Kotlin语言编写的轻量级SQL库的原型。 它确实具有两层数据库访问:包装DSL的类型安全SQL和轻量级数据访问对象。
查询方式
这是Exposed查询功能的简化图:
这是可以使用的方式:
objectWords:Table(){
valid=long("id").primaryKey().autoIncrement()
valdocId=long("docId")
valvalue=varchar("value",50)
}
Words.slice(Words.value,Words.value.count()).selectAll()
.groupBy(Words.value)
.orderBy(Words.id.count(),SortOrder.DESC)
.limit(25)
.map{
it[Words.value]toit[Words.value.count()]
}.toMap()
DDL,连接和交易
当然,Exposed不仅提供查询功能,还提供许多其他功能,例如连接到数据库。 这是代码中使用的图:
这是提供的功能的样本,以及代码样本:
-
表格创建
-
objectWords:Table(){ (1) valid=long("id").primaryKey().autoIncrement() valdocId=long("docId") valvalue=varchar("value",50) } SchemaUtils.create(Words) (2)
- 通过创建扩展提供的
Table
类的单例来定义Table
- 在数据库中创建表
数据库连接
- 通过创建扩展提供的
-
Database.connect( "jdbc:h2:mem:test", (1) "org.h2.Driver" (2) )
- JDBC URL
- JDBC驱动器类名称。 包含驱动程序的JAR必须可访问
交易处理
-
transaction{ createDbSchema() loadFileIntoDatabase(filename) query() }
transaction
块中定义的每个代码段都将在transaction
内部执行。 默认情况下,该事务是从线程local存储和检索的。
结论
至少可以说,在数据库中加载文本文件以执行查询并不是最佳选择。 实际上,这是一个非常糟糕的用例。
但是,在大多数情况下,让数据库完成所有工作是必经之路:请确保探索数据存储的所有功能,而不要通过语言提供的API在内存方面进行工作。
翻译自: https://blog.frankel.ch/exercises-programming-style/14/