如何生成满足多部分唯一键的最低 ID?
How do I generate the lowest id that satisfies a multi-part unqiue key?
以下架构和 INSERT
s:
DROP TABLE IF EXISTS foo_bar;
DROP TABLE IF EXISTS foo;
CREATE TABLE foo (
foo_id INT PRIMARY KEY NOT NULL GENERATED ALWAYS AS IDENTITY,
baz VARCHAR UNIQUE NOT NULL
);
CREATE TABLE foo_bar (
foo_id INT NOT NULL,
bar_id INT NOT NULL GENERATED ALWAYS AS IDENTITY,
quux VARCHAR UNIQUE NOT NULL,
FOREIGN KEY(foo_id) REFERENCES foo(foo_id),
PRIMARY KEY(bar_id, foo_id)
);
INSERT INTO foo(baz) VALUES('baz1');
INSERT INTO foo(baz) VALUES('baz2');
INSERT INTO foo_bar(foo_id, quux) VALUES(1, 'quux 1/1');
INSERT INTO foo_bar(foo_id, quux) VALUES(1, 'quux 1/2');
INSERT INTO foo_bar(foo_id, quux) VALUES(2, 'quux 2/1');
INSERT INTO foo_bar(foo_id, quux) VALUES(2, 'quux 2/2');
给出结果:
mud=> select * from foo;
foo_id | baz
--------+------
1 | baz1
2 | baz2
(2 rows)
mud=> select * from foo_bar;
foo_id | bar_id | quux
--------+--------+----------
1 | 1 | quux 1/1
1 | 2 | quux 1/2
2 | 3 | quux 2/1
2 | 4 | quux 2/2
(4 rows)
我希望生成的 bar_id
是满足 (foo_id, bar_id)
上的唯一主键约束的最低值。
即我希望结果是:
mud=> select * from foo;
foo_id | baz
--------+------
1 | baz1
2 | baz2
(2 rows)
mud=> select * from foo_bar;
foo_id | bar_id | quux
--------+--------+----------
1 | 1 | quux 1/1
1 | 2 | quux 1/2
2 | *1*| quux 2/1
2 | *2*| quux 2/2
(4 rows)
我怎样才能改变我的模式来实现这个目标?
不要这样做。
主键的唯一要求是它们的值需要唯一。它们是内部标识符,不会在 UI 中或通过外部 API 或其他方式暴露给用户。
如果您问这个问题,您可能想将它们暴露在某个地方,这是您设计中的一个大危险信号。
如果您确实需要显示自定义 ID,则可以创建一个额外的生成列,该列可以使用前缀、后缀、破折号进行格式化,并采用您想要的任何顺序或自定义逻辑。
以下架构和 INSERT
s:
DROP TABLE IF EXISTS foo_bar;
DROP TABLE IF EXISTS foo;
CREATE TABLE foo (
foo_id INT PRIMARY KEY NOT NULL GENERATED ALWAYS AS IDENTITY,
baz VARCHAR UNIQUE NOT NULL
);
CREATE TABLE foo_bar (
foo_id INT NOT NULL,
bar_id INT NOT NULL GENERATED ALWAYS AS IDENTITY,
quux VARCHAR UNIQUE NOT NULL,
FOREIGN KEY(foo_id) REFERENCES foo(foo_id),
PRIMARY KEY(bar_id, foo_id)
);
INSERT INTO foo(baz) VALUES('baz1');
INSERT INTO foo(baz) VALUES('baz2');
INSERT INTO foo_bar(foo_id, quux) VALUES(1, 'quux 1/1');
INSERT INTO foo_bar(foo_id, quux) VALUES(1, 'quux 1/2');
INSERT INTO foo_bar(foo_id, quux) VALUES(2, 'quux 2/1');
INSERT INTO foo_bar(foo_id, quux) VALUES(2, 'quux 2/2');
给出结果:
mud=> select * from foo;
foo_id | baz
--------+------
1 | baz1
2 | baz2
(2 rows)
mud=> select * from foo_bar;
foo_id | bar_id | quux
--------+--------+----------
1 | 1 | quux 1/1
1 | 2 | quux 1/2
2 | 3 | quux 2/1
2 | 4 | quux 2/2
(4 rows)
我希望生成的 bar_id
是满足 (foo_id, bar_id)
上的唯一主键约束的最低值。
即我希望结果是:
mud=> select * from foo;
foo_id | baz
--------+------
1 | baz1
2 | baz2
(2 rows)
mud=> select * from foo_bar;
foo_id | bar_id | quux
--------+--------+----------
1 | 1 | quux 1/1
1 | 2 | quux 1/2
2 | *1*| quux 2/1
2 | *2*| quux 2/2
(4 rows)
我怎样才能改变我的模式来实现这个目标?
不要这样做。
主键的唯一要求是它们的值需要唯一。它们是内部标识符,不会在 UI 中或通过外部 API 或其他方式暴露给用户。
如果您问这个问题,您可能想将它们暴露在某个地方,这是您设计中的一个大危险信号。
如果您确实需要显示自定义 ID,则可以创建一个额外的生成列,该列可以使用前缀、后缀、破折号进行格式化,并采用您想要的任何顺序或自定义逻辑。