PostgreSQL Varchar UID到Int UID,同时保留唯一性

说我有一个独特的列VarChar(32)。PostgreSQL Varchar UID到Int UID,同时保留唯一性

ex。 13bfa574e23848b68f1b7b5ff6d794e1

我想保留这个唯一性,同时将列转换为int。我想我可以将所有的字母都转换成相应的ascii,同时保留数字和字符位置。为此,我将使用翻译功能。

伪代码:select translate(uid, '[^0-9]', ascii('[^0-9]'))

我的问题是找到所有的字母在VARCHAR列原本。 我试过

select uid, substring(uid from '[^0-9]') from test_table;

但它只返回它遇到的第一个字母。使用上面的例子,我会寻找bfaebfbbffde

任何帮助表示赞赏!

回答:

首先,我同意两位评论者说你应该使用UID数据类型。

这一边......

你的UID看起来像一个传统的,因为它不是字母数字,这是十六进制。如果是这样的话,你可以使用这个解决方案的十六进制转换为数值:

PostgreSQL: convert hex string of a very large number to a NUMERIC

通知接受的解决方案(我的,耻辱)是不如其他解决方案上市,作为煤矿将不适用于这个大的十六进制值。

这就是说,这是一个巨大的数字。圣烟。

取决于表中有多少条记录和插入/更新的频率,我会考虑一种截然不同的方法。简而言之,我会创建另一列来存储您的数字ID,其值将由序列确定。

如果你真的想让它刀枪不入,你也可以创建一个交叉引用表来存储将

  1. 重用一个ID,如果它曾经多次(我知道的UID没有关系,但这将涵盖记录被错误删除的情况下,再次出现,并且要保留原来的ID)
  2. 如果UID的重复(比如这是每个UID多个记录的子表),这将覆盖情况以及

如果没有这些应用,你ç应该把它弄歪了一下。

该解决方案将是这个样子:

添加一个ID列,这将是你的数字相当于UID:

alter table test_table 

add column id bigint

创建一个序列:

CREATE SEQUENCE test_id 

创建交叉参考表(再次,对于虚拟版本不需要):

create table test_id_xref (

uid varchar(32) not null,

id bigint not null,

constraint test_id_xref_pk primary key (uid)

)

然后做一次更新替代ID分配给每个UID两种交叉引用和实际表:

insert into test_id_xref 

with uids as (

select distinct uid

from test_table

)

select uid, nextval ('test_id')

from uids;

update test_table tt

set id = x.id

from test_id_xref x

where tt.uid = x.uid;

最后,未来所有刀片,创建一个触发器来分配下一个值:

CREATE OR REPLACE FUNCTION test_table_insert_trigger() 

RETURNS trigger AS

$BODY$

BEGIN

select t.id

from test_id_xref t

into NEW.id

where t.uid = NEW.uid;

if NEW.id is null then

NEW.id := nextval('test_id');

insert into test_id_xref values (NEW.uid, NEW.id);

end if;

return NEW;

END;

$BODY$

LANGUAGE plpgsql VOLATILE

COST 100;

CREATE TRIGGER insert_test_table_trigger

BEFORE INSERT

ON test_table

FOR EACH ROW

EXECUTE PROCEDURE test_table_insert_trigger();

回答:

创建一个函数替换空白包车,你不是在串需要,

CREATE FUNCTION replace_char(v_string VARCHAR(32) CHARSET utf8) RETURNS VARCHAR(32) 

DETERMINISTIC

BEGIN

DECLARE v_return_string VARCHAR(32) DEFAULT '';

DECLARE v_remove_char VARCHAR(200) DEFAULT '1,2,3,4,5,6,7,8,9,0';

DECLARE v_length, j INT(3) DEFAULT 0;

SET v_length = LENGTH(v_string);

WHILE(j < v_length) DO

IF (FIND_IN_SET(SUBSTR(v_string, (j+1), 1), v_remove_char) = 0) THEN

SET v_return_string = CONCAT(v_return_string, SUBSTR(v_string, (j+1), 1));

END IF;

SET j = j+1;

END WHILE;

RETURN v_return_string;

END$$

DELIMITER ;

现在你只要东东调用这个函数在查询

select uid, replace_char(uid) from test_table; 

它会给你字符串你需要(bfaebfbbffde

如果你只想int数,即13574238486817567941那么改变变量的值和列数据类型在十进制(50,0)中,十进制可以存储大数,并且有小数点0,所以它将存储int值作为十进制。

v_remove_char = 'a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z'; 

以上是 PostgreSQL Varchar UID到Int UID,同时保留唯一性 的全部内容, 来源链接: utcz.com/qa/259699.html

回到顶部