我已经开始使用Java、Sping Boot 应用程序和PostgreSQL数据库构建一个银行项目。我想在每次创建新帐户时生成一个随机的8位或10位数的帐号。实现这一目标的最佳方法是什么?
选项1:我可以在创建新帐户时在Java服务层中处理此问题(但如何确保它是唯一的?).
选项2:我可以这样设计数据库:
CREATE TABLE IF NOT EXISTS account (
id SERIAL PRIMARY KEY,
account_number VARCHAR(8) UNIQUE, -- Unique 8-character account number
-- Other columns for account details
);
然后创建一个SQL函数来生成一个随机数,如:
CREATE OR REPLACE FUNCTION generate_random_account_number()
RETURNS VARCHAR(8) AS $$
BEGIN
RETURN lpad(floor(random() * 100000000)::int::text, 8, '0');
END;
$$ LANGUAGE plpgsql;
然后像这样插入:
INSERT INTO account (account_number, other_columns)
VALUES (generate_random_account_number(), 'other_data');
我不确定哪种方法更好地实现这一点,以及如何确保每次创建帐户时帐户号码都是唯一的。
PS:我不希望遇到独特性的问题,因为这是一个业余爱好项目,我不会创建超过100个帐户。
3条答案
按热度按时间wlzqhblo1#
我会这样做:
选项1:我可以在创建新帐户时在Java服务层中处理此问题
如何确保它是独一无二的?
创建随机帐号,创建后,执行数据库查询,返回带有该帐号的所有数据集。如果返回的结果数量大于0,则创建一个新的随机帐号并重新检查。循环执行此操作,直到数据库查询不返回任何数据集。
这个答案的原因是:
旧熨斗的尖头
现在,成长,成为最好的自己!
s1ag04yj2#
你需要一个从连续输入中可靠地生成10位数的函数,而且这个函数看起来是随机的,也就是说,不知道你的函数的人不会知道前一个数字后面是哪些数字。实现它的一种方法是定义一个模式。假设我们有一个大数的10位数倍数,比如9754031400
这是
12345 × 98765 × 8
所以我们可以
1 +(98765 * 1),1 +(98765 * 2),...,1 +(98765 * 98759)
作为我们的第一组数字(98765 + 1的倍数低于9754031400)。当我们在这个区间内用完了数字时,我们可以继续这个系列,将2加到倍数上:
2 +(98765 * 1),2 +(98765 * 2),...,2 +(98765 * 98759)
无可否认,这还不够令人困惑。所以我们可以把数字打乱。如果原始号码的数字最初是
d1 d2 d3 d4 d5 d6 d7 d8 d9 d10**
则可以更改它们的顺序,以使结果变得模糊
d10 d7 d5 d6 d3 d4 d8 d1 d9 d2**
这将是非常困难的逆向工程。但如果这还不够,您还可以添加更多级别的模糊处理。由于这是一个算法示例,而JavaScript是我们可以添加为片段的唯一语言,因此我将通过Javascript来说明这一点,但您可以在Java或SQL中实现此算法,没有任何问题
sc4hvdpw3#
我想每次生成一个随机的8位或10位数的帐号。
第一个问题是你为什么要这样做。如果这个数字必须满足特定的标准,请列出它们 * 精确 *。这个数字必须是真正的“随机”还是“任意”?为什么是数字,为什么是8或10?前导零可以吗?很重要?等
为什么额外的替代PK
id
?account_number
不是自然键吗?为什么varchar(8)
只是数字?想想由不同客户同时创建的多个帐户。数据库可以可靠地避免冲突,而客户端则相反。
除非有特定的条件,否则使用
bigint
IDENTITY
列。一个 * 任意的 *,但不是 * 随机的 * 数字。前导零是无关紧要的噪声:请参阅:
10位数对于普通的
integer
来说太多了。所以bigint
。我加入了一个
CHECK
约束来强制你的数字范围。要在一个步骤中插入并取回生成的
account_id
,请执行以下操作:如果您需要10位数的字符串格式,则始终可以设置数字的格式以便于显示。像
to_char(account_id, '0000000000')
或lpad(account_id::text, 10, '0')
-哪个更好,因为 * 不可变 *。如果需要,您甚至可以将生成的列添加到表中:请参阅:
真随机
如果你需要真正的随机数,其固有的缺点是原则上可能会发生冲突。
然后又道:
UUID
要使冲突几乎不可能发生,请使用
uuid
值而不是10位数。这些可以在客户端或in the database中生成。它们只是有点笨拙,占用16个字节。关于冲突的可能性,请参考章节 “哈希冲突的概率?“ 此处: