65.9K
CodeProject 正在变化。 阅读更多。
Home

NoSqlOnSql 简介: 在 SQL 上实现 NoSQL

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.50/5 (2投票s)

2020 年 10 月 13 日

CPOL

3分钟阅读

viewsIcon

11099

在 SQL 上实现 NoSQL

引言

NoSqlOnSql 基于增强 SQL 数据库以支持 NoSQL 功能,而无需任何内核更改。从这个意义上讲,它与其他倡议类似,例如 https://www.torodb.comhttps://www.microsoft.com/en-us/research/project/json-server-2/

但是,NoSqlOnSql 的方法是不同的,它不是在处理流程中挂钩中间件,而是在处理开始之前处理 NoSQL 语义。 NoSqlOnSql 被实现为一个源到源的转译器:NoSqlOnSql 语句被编译成常规 SQL 语句,这些语句由数据库正常执行。 这种编译可以在任何时候进行,甚至可以在创建数据库之前的查询开发期间进行。

NoSqlOnSql 能够创建、更新和查询文档,而无需任何模式定义。 文档使用类似于 JSON 的符号定义。

实现

SQL 实现因供应商而异。 除此之外,符合标准的程度也相当多样。 这意味着,不幸的是,NoSqlOnSql 的每个实现都必须针对特定的 SQL 风格。 NoSqlOnSql 的当前实现目标是 Transact-SQL 或 T-SQL。 这是 Microsoft SQL Server 中使用的语言。

此外,在当前的实现中考虑了以下事项

  • 任何有效的 SQL 语句都是有效的 NoSqlOnSql 语句。 SQL 和 NoSqlOnSql 语句可以组合。 NoSqlOnSql 被翻译成等效的 SQL 语句。 例如,可以从 NoSqlOnSql SELECT 查询创建 SQL 视图。
  • 实现应该尽可能少侵入。 NoSqlOnSql 创建的永久性工件的数量减少到 ONE 层次结构表,该表实现集合中的所有文档。
  • 在处理复杂查询时,NoSqlOnSql 可能需要创建临时对象,这些对象将在查询完成后被丢弃。 为了避免名称冲突,所有 NoSqlOnSql 对象都以 NOSQL_ 前缀开头。
  • NoSqlOnSql 遵循只写范例,数据永远不会被删除或更新。

如果需要更改值,则会创建该值的新版本。 因此

  • 默认情况下,只有值的最新版本可用,但可以访问文档的更改历史记录。 这使得 NoSqlOnSql 存储成为实现区块链的完美媒介。
  • 这种方法也遵循事件存储范例:https://en.wikipedia.org/wiki/Event_store
  • 在 SQL 层,实现集合只需要支持 INSERTSELECT。 也就是说,表上的任何记录都不会被修改或删除。 在考虑容错(即复制)和可扩展性(即分片)时,这提供了许多优势。

它看起来怎么样?

NoSqlOnSql 语法类似于 SQL,它遵循相同的语句、数据集和数据集操作范例。 所有 NoSqlOnSql 语句都以 nosql 开头。

NoSqlOnSql 完全集成在 SQL 中,两种类型的语句及其结果可以混合使用。

一个例子胜过一千个字,下面的例子是不言自明的。 此时,不要太注意语法,只需关注总体感觉以及 NoSqlOnSql 如何与 SQL 混合。

nosql create springfield override   
nosql insert {
    name: "Homer", 
    nationality:"US",
    age: 34, color:"green",  
    lastname:"Simpson" ,
    weight:90,
    likes:['football','doughnuts'], 
    children: [ 
              {name: "Bart",lastname:"Simpson",weight:38,age:10},
              {name:"Lisa",lastname:"Simpson",age:8,likes:['music']}
    ]
}   into springfield 
 
nosql insert { name: "Moe",lastname:"Szyslak",occupation:"bartender"}  into springfield 
       
nosql select ?,$name,$lastname,#age,$children[0].name as kid0 from springfield _
               where $Lastname='Simpson' 

这会返回:

     id | name  | lastname | age | kid0
     ----------------------------------
 0    1 | Homer | Simpson  |  34 | Bart
 1    4 | Bart  | Simpson  |  10 |
 2    5 | Lisa  | Simpson  |   8 |

安装和示例

用于 T-SQL 的 NoSqlOnSql 可作为 .NET Framework 的 NuGet 包提供。

Install-Package nosqlonsql -Version 1.0.1

使用它很简单,只需创建一个 NoSql 对象。

var nosql = new NoSql();  

使用 nosql 查询和支持的 SQL 方言类型调用 Transpile(“mssql”代表 MS SQL Server)。 false 结果表示语法错误

if (!nosql.Transpile(nosqlquery, "mssql")) throw new Exception(nosql.Error);

代码、注释和主机回调是转译的结果,但我们只对代码块感兴趣,这些代码块只是常规的 SQL 代码。 因此,我们像往常一样执行它们

using (var database=new SqlConnection(connectionString))
{
    for (var i = 0; i < nosql.Code.Length; i++)
    {
        if (nosql.Code[i].Type == BlockType.Code)
        {
            using (SqlCommand command = new SqlCommand(nosql.Code[i].Value, database))
            {
               using (var rs = command.ExecuteReader())
                 ...PROCESS AS USUAL !!
            }
        }
     }
}

更详细的示例可在 https://github.com/jsegarra1971/nosqlonsql/tree/master/Demo 获得。

反馈

NoSqlOnSql 尚未准备好投入生产。 目前,它只是一个概念验证 (PoC),旨在展示 SQL 和基于 NoSQL 文档之间的差距不是技术差距,而是概念差距。 因此,可以通过现有的功能以及一些思考来弥补它。

PoC 是有效且可靠的,但是将此转化为可操作产品所需的工作量不是我愿意独自承担的。 因此,如果您有兴趣扩展它,请给我留言或发表评论。

历史

  • 2020年10月12日:初版
© . All rights reserved.