mysql查询以连接不同表之间存储的uuid

2uluyalo  于 2021-06-25  发布在  Mysql
关注(0)|答案(3)|浏览(563)

我有一个uuid,它存储在一个表中作为人类可读的guid,但在另一个表中它被拆分为高位和低位。如何编写查询以联接uuid上的表?
编辑:表2将只有一个结果与给定的上限和下限位,所以希望效率不应该太可怕,但请考虑到这个问题的答案。

  1. table1.uuid = 'b33ac8a9-ae45-4120-bb6e-7537e271808e'
  2. table2.upper_bits = -5531888561172430560, table2.lower_bits = -4940882858296115058

我需要找回 table2.status 随着 table1.* 哪里 table2.upper_bits + table2.lower_bits = table1.uuid (pseudo where语句)但是我不知道如何为联接求table2的上下值之和,或者如何将table1的uuid转换为联接的位。
谢谢!

prdp8dxp

prdp8dxp1#

这里是@uuerdo解决方案的一个变体,应该更有效(有点像装饰连接取消装饰),但我还没有运行解释来确定:

  1. SELECT t1.*, t2.status
  2. FROM (
  3. SELECT UUID_TO_BIN(uuid) AS tmpid, *
  4. FROM table1
  5. ) AS t1 INNER JOIN (
  6. SELECT UUID_TO_BIN(CONCAT(HEX(upper_bits), HEX(lower_bits))) AS tmpid, status
  7. FROM table2
  8. ) AS t2 ON t1.tmpid = t2.tmpid

它可能会占用更多的内存,如果表有很多行和/或表1非常宽,则需要记住这一点。
如果您只需要表1和表2中与单个uuid匹配的记录,则应该只执行两个查询,而不是联接:

  1. SELECT *
  2. FROM table1
  3. WHERE UUID_TO_BIN(uuid) = UUID_TO_BIN(?)
  4. SELECT status
  5. FROM table2
  6. WHERE UUID_TO_BIN(CONCAT(HEX(upper_bits), HEX(lower_bits))) = UUID_TO_BIN(?)

如果 upper_bits 以及 lower_bits 如果已编制索引,这将是查询表2的更好方法:

  1. SET @tmpid = UUID_TO_BIN(?);
  2. SELECT status
  3. FROM table2
  4. WHERE upper_bits = @tmpid >> 64, lower_bits = _binary X'FFFFFFFFFFFFFFFF' & @tmpid

你可以将类似的逻辑应用到我的第一个解决方案中(我认为):

  1. SELECT t1.*, t2.status
  2. FROM (
  3. SELECT
  4. UUID_TO_BIN(uuid) >> 64 AS upper_bits,
  5. _binary X'FFFFFFFFFFFFFFFF' & UUID_TO_BIN(uuid) AS lower_bits,
  6. *
  7. FROM table1
  8. ) AS t1 INNER JOIN (
  9. SELECT upper_bits, lower_bits, status
  10. FROM table2
  11. ) AS t2 ON t1.upper_bits = t2.upper_bits AND t1.lower_bits = t2.lower_bits

这些都没有经过测试,但希望它能给你一些想法来玩。

展开查看全部
7gcisfzg

7gcisfzg2#

像这样的事情可能有用。。。但显然效率很低。

  1. SELECT ...
  2. FROM table1 AS t1
  3. INNER JOIN table2 AS t2 ON REPLACE(t1.uuid, '-', '')
  4. = CONCAT(HEX(t2.upper_bits), HEX(t2.lower_bits))
  5. ...

…您可能需要根据排序规则/比较强制使用大写/小写。
我倾向于认为更改数据库结构是“绝对必要的”(以回应您对另一个答案的评论)。为了尽量减少对现有查询和逻辑的影响,您可以将其中一个表更改为具有其他匹配字段,并向表中添加触发器以自动填充/更新新字段;然后执行一次更新以设置所有旧记录的值。
我会先尝试修改t1,因为两个int上的索引可能比一个字符串上的索引“更好”;但我不确定将字符串转换成高位和低位会有多直接。
修改t2会更容易,触发因素会比 SET NEW.uuid = CONCAT(HEX(NEW.upper_bits), HEX(NEW.lower_bits)); …我说“比”多一点,因为触发器最好同时插入 - ,因此连接条件可以消除所有函数的使用。
编辑:我找到了一种在纯sql中计算位的方法:

  1. SELECT @uuid := REPLACE('b33ac8a9-ae45-4120-bb6e-7537e271808e', '-', '') AS uuid
  2. , -1 * CAST((~CAST(CONV(SUBSTRING(@uuid, 1, 16), 16, 10) AS SIGNED) + 1) AS SIGNED) AS upper_bits
  3. , -1 * CAST((~CAST(CONV(SUBSTRING(@uuid, 17, 16), 16, 10) AS SIGNED) + 1) AS SIGNED) AS lower_bits
  4. ;

您可以在t1的触发器中使用类似的内容,并对新字段使用t1的一次性更新。
…它甚至可能有助于加入:

  1. ON -1 * CAST((~CAST(CONV(SUBSTRING(REPLACE(t1.uuid, '-', ''), 1, 16), 16, 10) AS SIGNED) + 1) AS SIGNED)
  2. = t2.upper_bits
  3. AND -1 * CAST((~CAST(CONV(SUBSTRING(REPLACE(t1.uuid, '-', ''), 17, 16), 16, 10) AS SIGNED) + 1) AS SIGNED)
  4. = t2.lower_bits

注意:是的,在这两个版本中过度的强制转换似乎是必要的(至少在我测试计算的mysql的旧版本上是如此)

展开查看全部
zpqajqem

zpqajqem3#

最简单的方法是将低位和高位与uuid一起存储在表1中。然后将表的低位和高位连接起来。
编辑:如果您只需要一行,并且您确定在另一个表中将有一个匹配的行,那么计算uuid=@uuid,较低的\u位=@lbits &高位=@ubits,然后运行以下命令:

  1. Select t1.*, t2.status
  2. From
  3. (select * from table1 where uuid = @uuid) as t1
  4. Cross join
  5. (select status from table2 where lower_bits =@lbits and upper_bits= @ubits) as t2;

相关问题