【问题标题】:Creating consistent integer from a string从字符串创建一致的整数
【发布时间】:2015-09-10 02:02:17
【问题描述】:

我在 SQL Server/Oracle db 的表中有各种字符串,如下所示:

 String1  
 String2  
 String3             

我需要将它们转换为正整数,比如:

String1 = 12  
String2 = 25  
String3 = 45    

我不希望这些数字按任何顺序排列。唯一的要求是为一个字符串生成的数字不应与其他字符串冲突。可以将新字符串插入表中,也可以删除旧字符串。现在稍后,如果我没有第二个字符串,而是有一个新字符串

String1 = 12    
String3 = 45    
String4 = 28    

请注意,之前为第二个字符串生成的数字 25 不能用于新字符串。 不允许使用额外的存储空间(临时表)。我使用了 row_number 函数,但后来意识到当插入新字符串时,使用此函数生成的整数会发生变化(因为字符串的顺序会发生变化)

注意:我的字符串是 128 位 GUID。

注意:如果允许我在本地服务器(而不是客户端计算机)上使用表(唯一整数 - GUID 映射),我如何确保没有为新的 GUID 字符串分配之前分配的整数?

我们将不胜感激任何解决此问题的意见。

【问题讨论】:

  • 身份列怎么样?
  • 不允许对数据库进行任何更改。数据库有一列具有唯一字符串。我需要使用 SELECT 查询来检索这些字符串并为它们分配唯一的整数。在第一次运行期间分配给字符串的编号在第二次运行期间也应该相同(考虑到字符串插入和删除可以从数据库中进行)。不允许创建临时表。
  • 系统要求您 (1) 存储信息,(2) 不使用存储空间。我认为这在逻辑上是不可能的。
  • 我可以知道你的整数是如何分配给字符串的吗?
  • 请解释为什么您需要数字。它不能是为了唯一性,因为您可以使用 GUID 来强制执行。

标签: sql sql-server oracle


【解决方案1】:

我更喜欢两种方法

  1. 使用身份列。

  2. 1234563之前的值被删除了。

编辑:得到您的要求后,我认为上述步骤不适合您。如果数据库结构没有任何变化,这对我来说是不现实的。如果你找到出路,一定会期待的。

【讨论】:

  • 我认为它符合 OP 的要求(因为他的最新编辑)。为每个唯一的 guid 记录一个不同的 int 直到没有更多的 int 是我能想到的将使用的 guid 映射到整数的唯一方法。此表不应允许删除以保留映射。
【解决方案2】:

更新

在知道我们正在处理 100 万条记录后,建议使用 ROWID 而不是散列。

SQL> create table temp as
select 'String1' s from dual union
select 'String2' s from dual union
select 'String3' s from dual;

Table created.

SQL> with t as (
  select s, dump(rowid) dump from temp
)
select s, rowid, replace(substr(dump,instr(dump,': ')+2),',') from t;

S       ROWID              REPLACE(SUBSTR(DUMP,INSTR(DUMP,':')+2),',')
------- ------------------ ----------------------------------------------------------
String1 AAAl4EAAEAAACUrAAA 0294410374300
String2 AAAl4EAAEAAACUrAAB 0294410374301
String3 AAAl4EAAEAAACUrAAC 0294410374302

上一个

听起来像 ORA_HASH 是最合适的。 https://docs.oracle.com/cd/B12037_01/server.101/b10759/functions097.htm

SQL> with t as (
  select 'String1' s from dual union
  select 'String2' s from dual union
  select 'String3' s from dual
)
select t.s, ora_hash(t.s) from t;

S       ORA_HASH(T.S)
------- -------------
String1    1383541721
String2    1227763854
String3    3134930256

下面列出了其他替代方法,但它们需要额外的步骤才能将字母转换为数字。

【讨论】:

  • 谢谢托克。我的字符串是 128 位 GUID。如果我将使用散列函数从这些 GUID 生成 32 位十进制,则有可能发生冲突。我不需要将整数转换回字符串。我正在考虑一种将 128 位 GUID 拆分为 4 个 32 位字符串的方法,生成每个拆分字符串的整数,然后以某种方式组合这些整数以生成唯一 ID。有没有一种算法可以保证这个过程的唯一性?
  • 如果我使用 java 函数从 128 位 GUID 字符串生成唯一整数,然后将此函数编译为 SQL Server/Oracle 存储过程,是否可行?
  • 另外,我需要唯一整数的最大字符串数仅在 100 万个范围内。如果我知道字符串的数量永远不会超过 100 万,我可以安全地使用哈希函数吗?
  • 一般来说,hash 发生碰撞的几率很小。 preshing.com/20110504/hash-collision-probabilities 建议改用 ROWID 方法,因为它在同一个表中为您提供了不同的值。 (注意它改变的场景)
猜你喜欢
  • 1970-01-01
  • 2016-10-18
  • 1970-01-01
  • 2016-08-16
  • 2010-11-15
  • 1970-01-01
  • 2010-11-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多