sql group by having用法_【一个idea】YesSql,一种在经典nosql数据库redis上实现SQL引擎的方案(我就要开历史的倒车)...

最高级的红酒,一定要掺上雪碧才好喝。
基于这样的品味,我设计出了一套在经典nosql数据库redis上实现SQL引擎的方法。既然redis号称nosql,而我偏要把SQL加到redis上,于是这个技术方案取名为【YesSql】。

8c966f47542863e17725dc3d1f8f867e.png

1.在redis上实现SQL查询的技术基础

  • redis上可以执行lua。整个SQL引擎就是在lua上解析SQL语句,执行,并返回结果。

  • lua有很好的正则表达式引擎,因此解析SQL语法变得简单。

  • redis提供map, zset这样的数据结构,很容易实现列存储

  • 关系数据库不也就是索引+遍历,核心逻辑完全能用lua来实现。

2.实现细节

2.1 create table

  • 假定我只支持number和string两种数据结构

  • 把整个按行组织的表看成由N个字段组成的列存储

    • 也就是说,字段的组织是:table_column -> map 或 zset

    • 用一个 table_rowid -> int 来产生一个rowid

    • map或者zset中的key使用rowid:

${table}_rowid -> int_value
${table}_${column1} -> map
${rowid1} -> column1 data of row 1
${rowid2} -> column1 data of row 2
${table}_${column2} -> map
${rowid1} -> column2 data of row 1
${rowid2} -> column2 data of row 2
  • 可以有唯一索引:

${table}_unique_index_1 -> map
${unique_key_1} -> rowid1
${unique_key_2} -> rowid
  • 可以有数值类型的排序索引:

${table}_number_index_1 -> zset
$rowid1 -> number1
$rowid2 -> number2
  • 所以:create table就是建立上面的KEY结构

  • 建表的语法大致如下:

create table my_first_redis_table_1(
column1 number,
column2 string,
column2 number
unique index column2,
number_index column3
)

2.2 insert

  • 插入时先要使用redis的INC指令得到一个新的rowid

  • 插入其实就是在${table}_${column}字段的下面增加二级KEY

2.3 update

  • update可以指定rowid或者唯一索引中的字段

  • 如果where条件比较复杂,则只能遍历字段,并最终取多个rowid集合的交集

  • set中的字段,先找到rowid,然后根据rowid更新就好了

2.3 delete

  • where条件中的搜索如同上面

  • 删除行就是逐个删除每个column key下面的rowid对应的二级KEY

2.4 select

这部分相对复杂,划分为不同的场景:

2.4.1 from部分

解析出表名是第一步的,然后就确定了KEY的前缀。

2.4.2 where条件

上面讲update和delete的where部分一笔带过了,具体有这样的一些场景:

  • 使用rowid=xxx或者rowid in ()的方式,比较简单

  • 使用unique_key=xxx或者unique_key in ()的方式,也比较简单,先通过唯一索引得到rowid,然后再根据rowid查询

  • 使用number_index的范围查询的情况,先使用ZRANGEBYSCORE找到多个rowid,然后再查询

  • 使用and/or/in及其其他字段上的表达式,无非也就是层层加过滤,知道最终确定rowid的集合

2.4.3 select部分

  • 每选择一个列,就意味着要输出这个列的值给查询方

  • 字段上的表达式,也比较容易实现

2.4.4 group by部分

  • 可以建立一个所有group by中字段名组合起来的临时KEY作为二级KEY的map

例如:
select column1, column2, count(1), sum(column3)
from table
group by column1, column2

可以建立这样的KEY结构:
temp_group_by_1 -> map
${column1_value}_${column2_value} -> rowid
temp_group_by_1_stat1 -> map
$rowid1 -> count_value
temp_group_by_1_stat2 -> map
$rowid1 -> sum_value

2.4.5 having部分

  • having部分,也就是在上一步汇总好的基础上,对rowid指向的值做过滤。

  • 还有一个优化点:如果没有having字句,汇总采用map结构;有having字句,采用zset结构,直接根据范围做过滤

2.4.6 join部分

不再叙述,猜测不会有那么无聊的人真的希望用上这么一套SQL引擎。

3.最后

  • 这是一个恶意的玩笑

  • 某种程度上可以作为一种思维训练,让我们知道SQL引擎可能是怎么去运行的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值