gpt4 book ai didi

url 的 postgresql 唯一非连续 id

转载 作者:行者123 更新时间:2023-11-29 12:50:11 25 4
gpt4 key购买 nike

我看过一些在 Stackoverflow 上创建字母数字 ID 的方法,但它们都有自己的弱点,有些没有检查冲突,有些使用的序列在使用逻辑复制时不是一个好的选择。

谷歌搜索后我找到了this具有以下脚本的网站,该脚本检查冲突并且不使用序列。然而,这是在表中插入一行时作为触发器完成的。

-- Create a trigger function that takes no arguments.
-- Trigger functions automatically have OLD, NEW records
-- and TG_TABLE_NAME as well as others.
CREATE OR REPLACE FUNCTION unique_short_id()
RETURNS TRIGGER AS $$

-- Declare the variables we'll be using.
DECLARE
key TEXT;
qry TEXT;
found TEXT;
BEGIN

-- generate the first part of a query as a string with safely
-- escaped table name, using || to concat the parts
qry := 'SELECT id FROM ' || quote_ident(TG_TABLE_NAME) || ' WHERE id=';

-- This loop will probably only run once per call until we've generated
-- millions of ids.
LOOP

-- Generate our string bytes and re-encode as a base64 string.
key := encode(gen_random_bytes(6), 'base64');

-- Base64 encoding contains 2 URL unsafe characters by default.
-- The URL-safe version has these replacements.
key := replace(key, '/', '_'); -- url safe replacement
key := replace(key, '+', '-'); -- url safe replacement

-- Concat the generated key (safely quoted) with the generated query
-- and run it.
-- SELECT id FROM "test" WHERE id='blahblah' INTO found
-- Now "found" will be the duplicated id or NULL.
EXECUTE qry || quote_literal(key) INTO found;

-- Check to see if found is NULL.
-- If we checked to see if found = NULL it would always be FALSE
-- because (NULL = NULL) is always FALSE.
IF found IS NULL THEN

-- If we didn't find a collision then leave the LOOP.
EXIT;
END IF;

-- We haven't EXITed yet, so return to the top of the LOOP
-- and try again.
END LOOP;

-- NEW and OLD are available in TRIGGER PROCEDURES.
-- NEW is the mutated row that will actually be INSERTed.
-- We're replacing id, regardless of what it was before
-- with our key variable.
NEW.id = key;

-- The RECORD returned here is what will actually be INSERTed,
-- or what the next trigger will get if there is one.
RETURN NEW;
END;
$$ language 'plpgsql';

我有一个已经包含数据的表,我添加了一个名为 pid 的新列是否可以修改它并使用函数调用作为默认值,以便我之前的所有数据都变得简短身份证号?

最佳答案

假设你有一个表test:

DROP TABLE IF EXISTS test;
CREATE TABLE test (foo text, bar int);
INSERT INTO test (foo, bar) VALUES ('A', 1), ('B', 2);

您可以向其中添加一个 id 列:

ALTER TABLE test ADD COLUMN id text;

并附加触发器:

DROP TRIGGER IF EXISTS unique_short_id_on_test ON test;
CREATE TRIGGER unique_short_id_on_test
BEFORE INSERT ON test
FOR EACH ROW EXECUTE PROCEDURE unique_short_id();

现在创建一个临时表,temp,具有与测试相同的结构(但没有数据):

DROP TABLE IF EXISTS temp;
CREATE TABLE temp (LIKE test INCLUDING ALL);
CREATE TRIGGER unique_short_id_on_temp
BEFORE INSERT ON temp
FOR EACH ROW EXECUTE PROCEDURE unique_short_id();

test 注入(inject) temp:

INSERT INTO temp (foo, bar)
SELECT foo, bar
FROM test
RETURNING *

产生类似的东西:

| foo        | bar | id       |
|------------+-----+----------|
| A | 1 | 9yt9XQwm |
| B | 2 | LCeiA-P8 |

如果其他表在 test 表上有外键引用,或者如果 test 必须保持在线,可能无法删除 test 并将 temp 重命名为 test。相反,使用 temp 中的 id 更新 test 会更安全。

假设test有一个主键(为了具体起见,我们称它为testid),那么您可以使用 temp 中的 id 更新 test,使用:

UPDATE test
SET id = temp.id
FROM temp
WHERE test.testid = temp.testid;

然后你可以删除 temp 表:

DROP TABLE temp;

关于url 的 postgresql 唯一非连续 id,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56081894/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com