使用以 table 标识号为后缀的 ID 有什么缺点?
What are the disadvantages in using IDs suffixed by a table identifying number?
我正在玩:
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 在整个数据库中都是唯一的,消除了错误的 table 错误。
- 没有一个 id 的值小于 10,000,消除了与大多数迭代计数器的混淆。
- 包含table很容易从任何id的最后两位数中得知。
缺点:
- 我们浪费了 99% 的 ID。
还有哪些缺点是我没有考虑到的?
如评论所述,有充分的理由不去那里。规范地,代理 PK 是其 table 中行 的唯一标识符,不携带附加信息。
我还没有遇到过“错误-table 错误”或“与迭代计数器混淆”的情况。将整数 (int4
) PK 的键 space 减少 99% 可能会在以后咬你一口,同时将自己限制在最多 100 tables。如果您开始依赖数字的含义(我不建议这样做),您最好确保新的table遵守规则。并且没有人插入手动 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 100
、MINVALUE 2 INCREMENT 100
等代替人工计算
②用bigint
多补减键space.
此外,奇怪的是,您将如此多的精力投入到整个数据库的唯一 ID,然后使用非描述性、重复的列名称,如 id
。 txns_id
是更好的命名约定。
缺点:更容易受到 setval()
或 ALTER SEQUENCE
破坏制度的影响。
撤销所有普通用户对序列的 UPDATE
权限。
我正在玩:
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 在整个数据库中都是唯一的,消除了错误的 table 错误。
- 没有一个 id 的值小于 10,000,消除了与大多数迭代计数器的混淆。
- 包含table很容易从任何id的最后两位数中得知。
缺点:
- 我们浪费了 99% 的 ID。
还有哪些缺点是我没有考虑到的?
如评论所述,有充分的理由不去那里。规范地,代理 PK 是其 table 中行 的唯一标识符,不携带附加信息。
我还没有遇到过“错误-table 错误”或“与迭代计数器混淆”的情况。将整数 (int4
) PK 的键 space 减少 99% 可能会在以后咬你一口,同时将自己限制在最多 100 tables。如果您开始依赖数字的含义(我不建议这样做),您最好确保新的table遵守规则。并且没有人插入手动 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 100
、MINVALUE 2 INCREMENT 100
等代替人工计算
②用bigint
多补减键space.
此外,奇怪的是,您将如此多的精力投入到整个数据库的唯一 ID,然后使用非描述性、重复的列名称,如 id
。 txns_id
是更好的命名约定。
缺点:更容易受到 setval()
或 ALTER SEQUENCE
破坏制度的影响。
撤销所有普通用户对序列的 UPDATE
权限。