0

我正在玩:

DROP TABLE users CASCADE;
CREATE SEQUENCE users_id_seq MINVALUE 100;
CREATE TABLE users (
    id INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('users_id_seq') * 100 + 1,
    ...
);
ALTER SEQUENCE users_id_seq OWNED BY users.id;

DROP TABLE txns CASCADE;
CREATE SEQUENCE txns_seq MINVALUE 100;
CREATE TABLE txns (
    id INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('txns_seq') * 100 + 2,
    ...
);
ALTER SEQUENCE txns_seq OWNED BY txns.id;
...

在我看来,这有以下好处:

  • 每个 id 在整个数据库中都是唯一的,从而消除了错误的表错误。
  • 没有 id 的值小于 10,000,消除了与大多数迭代计数器的混淆。
  • 包含表很容易从任何 id 的最后两位数字中学习。

缺点:

  • 我们浪费了 99% 的 ID。

我没有考虑到哪些其他缺点?

4

1 回答 1

2

正如已经评论的那样,有充分的理由不去那里。典型地,代理 PK 是其表中行的唯一标识符,不携带附加信息。

我还没有遇到过“错误表错误”或“与迭代计数器混淆”的情况。将整数 ( int4) PK 的键空间减少 99% 可能会在以后对您不利,并且将自己限制为最多 100 个表。如果您开始依赖数字的含义(我建议不要这样做),您最好确保新表遵守规则。并且没有人插入手动 ID 值或更改 ID 值......

也就是说,如果你去那里,请考虑:

CREATE SEQUENCE users_id_seq MINVALUE 1 INCREMENT 100;  -- ①
CREATE TABLE users (
    users_id bigint PRIMARY KEY DEFAULT nextval('users_id_seq'), -- ②
    ...
);
ALTER SEQUENCE users_id_seq OWNED BY users.id;

CREATE SEQUENCE txns_id_seq MINVALUE 2 INCREMENT 100;
CREATE TABLE txns (
    txns_id bigint PRIMARY KEY DEFAULT nextval('txns_id_seq'),
    ...
);
ALTER SEQUENCE txns_id_seq OWNED BY txns.id;

① 使用MINVALUE 1 INCREMENT 100MINVALUE 2 INCREMENT 100代替人工计算。

bigint多用于弥补减少的键空间。
此外,奇怪的是,您在数据库中的唯一 ID 上投入了如此多的精力,然后使用非描述性、重复的列名,例如id. txns_id是更好的命名约定。

缺点:更容易受到setval()ALTER SEQUENCE破坏政权。撤销UPDATE所有普通用户对序列的权限。

于 2021-02-20T10:16:26.160 回答