Skip to main content

Azure Data Explorer(ADX)中如何修改表的列类型

分类:  Azure Data Explorer 标签:  #基础 #大数据 发布于: 2023-08-07 20:23:25

我们在Azure Data Explorer(ADX)中创建了一张表,例如如下的语法:

.create table test1 (['id']: int, name: string, ob_length: string);

现在我们有一个需求:需要更改列ob_length 从类型string更改类型到long

针对这个需求,大家第一映像肯定是直接使用alter column语法来更改就好了啊。语法也很简单:

.alter column ['test1'].['ob_length'] type=long

好像看起来也没什么问题,但是很不巧,官方的文档明确的针对这个指令有一个说明:

警告
When altering the data type of a column, any pre-existing data in that column will return a null value in future queries. After Using .alter column, that data cannot be recovered, even by using another command to alter the column type back to a previous value.

而且还是一个警告,意思也很简单,其实就是说更改列类型会造成数据丢失,同时原文档还给出一个不会丢失数据的解决方案:

.create table test1_prime (['id']: int, name: string, ob_length: long);

// Append data to the new table
.set-or-append test1_prime <| test1 | extend ob_length=tolong(ob_length)

// Rename tables
.rename tables test1_prime = test1, test1 = test1_prime

// Drop table T1_prime, which now has the old schema and data
.drop table test1_test1

这个方案也简单: 无非就是新建一个表,这个表的字段ob_length默认就是long类型,然后将原始表的所有数据都是转移到新表里,转移的时候做一个类型转换,最后交换一下表名字,删除无用的表就结束了。

乍看起来这确实是一个好办法,让我们继续深入一步:
假如你的原始表里有超过几十亿的数据,那么上面这个方法还适用吗?

当然是不适用!

有没有其他办法?

还是有的,如下代码:

-- 还是新建一个表
.create table test1_prime (['id']: int, name: string, ob_length: long);

--然后新建一个函数,要求这个函数的名字和原始表的名字是一致的,例如本例该函数的名字就应该是`test1`
.create-or-alter function  test1() {
   union ( test1_prime | project id, name, ob_length = tolong(ob_length)), (test1 | project id, name, ob_length = tolong(ob_length))
}

-- 然后交换新表和旧表的名字
.rename tables test1_prime = test1, test1 = test1_prime

但是这次我们不要删除任何表,同时保持两张表都存在,这样的话,查询会查询旧表(现在的名字是test1_prime),但是新插入的数据会进入到新表(现在的名字是test1),查询时会自动使用函数的值返回,这样等待数据的保存期超过了之后,再删除旧表就好了。