【问题标题】:Modulo arithmetic in Bigquery. Compute `x % y`, where `x` is a 128-bit numberBigquery 中的模运算。计算 `x % y`,其中 `x` 是一个 128 位数字
【发布时间】:2019-12-24 01:11:31
【问题描述】:

将字符串的 MD5 作为整数 x 的 128 位表示,我如何在 Google Bigquery 中计算 x % y,其中 y 通常相对较小(大约 1000)?

Bigquery 有一个 MD5 函数,返回类型为 BYTES 的 16 字节(即 128 位)的结果。

(背景:这是为了计算确定性的伪随机数。但是,出于遗留和兼容性的原因,我对算法没有灵活性!尽管我们知道它有一个(very slight) bias。)

这需要每天针对不同的输入字符串和不同的模数进行数百万/数十亿次,因此希望它可以有效地完成。作为后备,我可以用另一种语言在外部计算它,然后上传到 Bigquery;但如果我可以直接在 Bigquery 中执行此操作,那就太好了。

我研究了很多数论,所以也许我们可以使用一些数学技巧。但是,我仍然停留在更基本的 BiqQuery 问题上

  • 如何将字节数组转换为某种“大整数”类型?
  • 我可以访问 BYTES 数组中的字节子范围吗?
  • 给定一个字节(或者可能是四个字节?),我可以将其转换为可以应用算术运算的整数类型吗?

【问题讨论】:

    标签: sql google-bigquery modulo largenumber


    【解决方案1】:

    使用 power of math 和一个较长的 SQL 函数:

    CREATE TEMP FUNCTION modulo_md5(str ANY TYPE, m ANY TYPE) AS ((
      SELECT MOD(MOD(MOD(MOD(MOD(MOD(MOD(MOD(MOD(MOD(MOD(MOD(MOD(MOD(MOD(MOD(0 
        * 256 + num[OFFSET(0)], m ) 
        * 256 + num[OFFSET(1)], m )  
        * 256 + num[OFFSET(2)], m ) 
        * 256 + num[OFFSET(3)], m ) 
        * 256 + num[OFFSET(4)], m )  
        * 256 + num[OFFSET(5)], m ) 
        * 256 + num[OFFSET(6)], m ) 
        * 256 + num[OFFSET(7)], m )  
        * 256 + num[OFFSET(8)], m ) 
        * 256 + num[OFFSET(9)], m ) 
        * 256 + num[OFFSET(10)], m )  
        * 256 + num[OFFSET(11)], m ) 
        * 256 + num[OFFSET(12)], m ) 
        * 256 + num[OFFSET(13)], m )  
        * 256 + num[OFFSET(14)], m ) 
        * 256 + num[OFFSET(15)], m ) 
      FROM (SELECT TO_CODE_POINTS(MD5(str)) num)
    ));
    
    
    SELECT title, modulo_md5(title, 177) result, TO_HEX(MD5(title)) md5
    FROM `fh-bigquery.wikipedia_v3.pageviews_2019` 
    WHERE wiki='en'
    LIMIT 100000
    

    现在您可以将其用作持久共享 UDF:

    SELECT fhoffa.x.modulo_md5("any string", 177) result
    

    【讨论】:

    • 非常感谢。我很惊讶它的速度有多快,每分钟计算数百万个条目!我采用了稍微不同的方法,使用to_code_points(md5(the_string)) 直接获取整数数组。
    猜你喜欢
    • 2022-06-22
    • 1970-01-01
    • 2012-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多