BMG:Ruby语言中的产品化就绪关系代数

2020-07-14 23:13:59

BMG是作为Ruby库实现的关系代数。它将这种关系作为几年前与阿尔夫共同贡献的一流公民范式来实施。

与ALF一样,BMG可用于从各种文件、SQL数据库和任何可视为服务关系的数据源查询内存中的关系。与ALF一样,也支持跨数据源联接。

与Alf不同,BMG不做任何核心Ruby扩展,只公开面向对象的语法(不是Alf的函数语法)。BMG的实现也要简单得多,并且更容易实现用户定义的关系。

要求';bmg';要求';json';供应商=bmg::Relation.new([{sid:";s1";,名称:";史密斯";,状态:20,城市:";伦敦";},{sid:";s2";,名称:";琼斯";,状态:10,城市:";巴黎";},{sid:";s2";,名称:";琼斯";,状态:10,城市:";巴黎";},{sid:";s3";,名称:";布莱克&34;,状态:30,城市:";巴黎";},{sid:";s4";,名称:";克拉克&34;,状态:20,城市:";伦敦";},{sid:";s5";,名称:";亚当斯&34;,状态:30,城市:";雅典";}])BY_CITY=供应商.restricte(Predicate.neq(状态:30)).EXTEND(upname:->;(T){t[:name].upcase}).group([:SID,:Name,:Status],:Supplier_in)放置JSON.Pretty_GENERATE(BY_CITY)#[{.},.]。

Required';sqlite3';Required';bmg/Sequel';DB=Sequel.connect(";sqlite://suppliers-and-parts.db";)suppliers=Bmg.Sequel(:Supplies,DB)BIG_SUPPLIERS=Supplier.restriction(Predicate.neq(status:30))put BIG_Suppliers.to_sql#select`t1`.`sid`,`t1`.`name`,`t1`.`status`,`t1`.`status`,`t1`.。其中(`t1`.`status`!=30)放置JSON.Pretty_GENERATE(BIG_SUPPLIERS)#[{.},.]。

您可能知道的库(Sequel、Arel、SQLAlChemy、Korma、jOOQ等)。不要实现真正的关系代数:它们对链接关系运算符的支持是有限的(会产生错误或错误的SQL查询)。BMG始终允许链运算符。如果没有,它就会出现错误。换句话说,以下查询是100%有效的:

BMG支持内存关系、JSON关系、CSV关系、SQL关系等。它对SQL生成并不严格,并且支持跨多个数据源的查询。

BMG尽了最大努力优化查询,简化了生成的SQL代码(对数据源的低级访问)和内存操作。

BMG支持多种结构化操作符(分组、图像、自动打包、自动汇总等)。并允许建立非平坦关系。

我们有信心将BMG用于生产。不过,建议对查询计划进行系统检查。ALF太过实验性,不能在(关键的)生产系统上使用。

ALF公开了函数语法、命令行工具、REST风格的工具等等。BMG仅限于核心代数、主关系抽象和SQL生成。

BMG在遵守关系理论方面不那么严格,实际上可能会公开非关系特性(如支持NULL、LEFT_JOIN运算符等)。锋利的工具会受伤,使用时要格外小心。

BMG还没有实现try-alf.org上记录的所有操作符,即使我们计划最终支持所有操作符。

BMG有几个额外的运算符,在实际生产用例中被证明非常有用:前缀、后缀、自动捕获、自动汇总、LEFT_JOIN、rxMatch等。

r.allbut([:A,:B,.])#删除指定的属性r.auowrap(Split:';_';)#构造平面关系,Split:';_';是默认值。autosummarize([:A,:B,.],x::sum)#(实验性)通常支持的汇总器.Constants(x:12,.)#添加常量属性(有时在联合中有用)r.Extended(x:(T){.},.)#添加计算属性rgroup([:A,:B,.],:x)#从属性r.image(right,:x,[:A,:B,.])#从另一个关系添加关系值属性。join(right,[:A,:B,.])#连接键上的自然连接.join(right,:A=>;:x,:B=>;:Y,.)#右反转重命名后的自然连接.Left_Join(right,[:A,:B,.],{.})#使用可选的默认右元组进行左连接。Left_Join(Right,{:A=>;用法:x,.},{.})#右反转重命名后的左联接。匹配(right,[:A,:B,.])#半联接,也就是其中存在的。匹配(right,:A=>;:x,:b=>;)。:Y,.)#Semi JOIN,右反转重命名r.not_matching(right,[:A,:B,.])#反向Semi JOIN,又名WHERE NOT EXISISSERS r.not_matching(right,:A=>;用法:x,.)#反向半联接,右反转重命名r.page([[:a,:asc],.],12,page_size:10)#分页,使用显式orderingr.prefix(:foo_,但是:[:a,.])#prefix种类的renamingr.project([:a,:b,.])#仅保留指定属性r.rename(a::x,b::y,.)#重命名某些属性r.restricte(a:";foo";,b:";bar";,.)#关系限制,也称为.rxMatch([:A,:B,.],/xxx/)#regex匹配限制种类r.Summary([:A,:B,.],x::sum)#关系摘要r.Suffix(:_foo,但是:[:A,.])#后缀种类Renamingr.Union(右)#关系联合。

请随时联系我们寻求帮助、想法和/或贡献。如果涉及代码,请尽可能使用githubIssues和拉取请求。