应用介绍
装置和配置
应用自定义函数

sycnany-SQL作为SQL运行引擎并不需要提前定义Schema信息,而且很多数据源自身就是无Schema信息的,例如NoSQL数据库MongoDB,所以从数据源查问数据和运行计算默认间接应用输出数据的类型实现查问和计算,此时查问数据或执行计算可能因数据类型不匹配产生查问失败或计算出现异常,因而咱们能够在编写SQL时须要时能够手动增加数据类型注解或应用数据类型转换函数实现数据类型转换,以保障失去正确的查问或计算结果。

例如:

MongoDB的ObjectId保留在MySQL中个别转换为字符串应用varchar类型存储,后续在MongoDB和MySQL进行Join关联查问时,就需把MySQL存储的varchar类型转换为MongoDB的ObjectId能力正确的从MongoDB中加载出关联数据。

sycnany-SQL反对两种形式实现数据类型转换:

  • 应用类型注解
  • 应用类型转换函数

如无非凡阐明,后续示例中咱们假如有如下数据结构:

# MySQL中mysql_test库users表构造如下CREATE TABLE `mysql_test`.`users` (  `user_id` bigint(20) NOT NULL,  `name` varchar(64),  `birthday` varchar(20),  `vip_id` varchar(24),  PRIMARY KEY (`user_id`) USING BTREE);
# MongoDB中mongo_test库vips汇合有如下数据[{    "_id": ObjectId("640a9786bb450457c544f759"),    "vip_name" : "超级VIP",    "create_time" : ISODate("2023-03-10T02:35:50.298Z")}]

类型注解应用

在查问字段上增加该字段的类型注解信息,从数据源加载数据后会主动转换为该类型再参加后续查问或计算。

应用语法: `字段名[类型]`

例如:

# 编写Join查问SQLselect a.`user_id`, a.`name`, a.`birthday[date]`, b.`_id[text]` as vip_id, b.`vip_name` from `mysql_test`.`users` a left join `mongo_test`.`vips` b on a.`vip_id[objectid]`=b.`_id`;

在该SQL中咱们为users表的birthday字段增加了date类型注解,示意该字段需由MySQL表中保留的字符串日期类型转换为date数据类型。

而MySQL表中保留vip_id字段为MongoDB中vips汇合的主键_id字段的值,在users表和vips汇合join查问时,为users表的vip_id字段增加了objectid类型注解,在从MongoDB查问关联数据前转换为ObjectId,从而失常查问读取出关联数据。

从vips汇合加载数据胜利后,咱们又应用类型注解把注解_id字段从ObjectId转换为了字符串类型,以便能输入查问后果。

留神:类型注解只能增加在查问字段中并且字段肯定要用``包裹,不能用于as后alias名称和函数返回值。

反对的注解类型:

  • 整型数字:int、tinyint、smallint、mediumint、bigint
  • 浮点型数字:float、double
  • 字符串:str、tinytext、mediumtext、text、char、varchar、nchar
  • 字节数组:bytes、binary、varbinary、blob
  • 布尔型:bool、boolean
  • Decimal:decimal
  • BSON ObjectId: objectid
  • UUID:uuid
  • 日期工夫:datetime、timestamp
  • 日期:date
  • 工夫:time
  • 数组:array
  • 汇合:set
  • HashMap: map

类型转换函数应用

类型注解只能增加在查问字段上,但类型转换函数可在查问字段或函数返回值中应用,应用更不便,同时针对内置函数不能满足类型转换的需要,也能够自行编写加载自定义函数来实现类型转换,以便正确的实现查问或计算。

例如:

# 编写Join查问SQLselect a.`user_id`, a.`name`, convert_date(a.`birthday`) as birthday, convert_string(b.`_id`) as vip_id, b.`vip_name` from `mysql_test`.`users` a left join `mongo_test`.`vips` b on convert_objectid(a.`vip_id`)=b.`_id`;

应用类型转换函数也可实现雷同操作。

内置反对的类型转换函数:

  • 转为整型数字:convert_int(expr)
  • 转为浮点型数字:convert_float(expr)
  • 转为字符串:convert_string(expr)
  • 转为字节数组:convert_bytes(expr)
  • 转为布尔型:convert_bool(expr)
  • 转为Decimal:convert_decimal(expr)
  • 转为BSON ObjectId:convert_objectid(expr)
  • 转为UUID:convert_uuid(expr)
  • 转为日期工夫:convert_datetime(expr)
  • 转为日期:convert_date(expr)
  • 转为工夫:convert_time(expr)
  • 转为数组:convert_array(expr)
  • 转为汇合:convert_set(expr)
  • 转为HashMap:convert_map(expr)

针对Join查问On关联条件的特地优化提醒

在进行Join关联查问时,On条件编写时可能须要解决类型统一能力从关联表中正确查问出数据,而不同数据源可能有不同反对,如MySQL等SQL类型数据库会自定进行类型转换,MongoDB则必须手动转换保留查问条件类型统一,所以类型转换的字段不应该在需读取关联数据的表上。

例如,对于下面的示例SQL,退出咱们改写为以下SQL:

# 编写Join查问SQLselect a.`user_id`, a.`name`, convert_date(a.`birthday`) as birthday, convert_string(b.`_id`) as vip_id, b.`vip_name` from `mysql_test`.`users` a left join `mongo_test`.`vips` b on a.`vip_id`=convert_string(b.`_id`);

尽管以上SQL也能失常执行,但因为Join条件中关联表vips的_id字段存在类型手动类型转换,所以须要加载整个表的数据后在内存中实现计算匹配,不能间接应用MongoDB查问语句间接从数据库中间接读取出须要数据,不能应用数据库的索引优化、效率很低且可能因耗费过多资源而出现异常,所以咱们应该把类型转换放在users表的vip_id字段上,即:

# 编写Join查问SQLselect a.`user_id`, a.`name`, convert_date(a.`birthday`) as birthday, convert_string(b.`_id`) as vip_id, b.`vip_name` from `mysql_test`.`users` a left join `mongo_test`.`vips` b on convert_objectid(a.`vip_id`)=b.`_id`;