如何为 postgresql 序列指定值列表

发布于 2024-12-10 07:44:47 字数 360 浏览 0 评论 0原文

我有一个整数值列表 X,我希望表 Y 的主键来自该整数值列表。我想知道这是否可以使用序列来完成。换句话说:有没有办法告诉 PostgreSQL 序列使用此列表 X 为我的表 Y 生成主键?

实现此目的的一种方法是使用一个序列,其中包含列表 X 中最后使用的整数的索引,在该序列上调用 setval(),获取下一个值并尝试将其插入到我的表 Y 中。如果并发请求,将会出现错误,在这种情况下,我需要尝试使用列表 X 中的下一个值。我想知道还有哪些其他(更好)的方法来实现我打算做的事情。

I have a list of integer values X and I want a primary key for my table Y to come from that list of integer values. I was wondering if this could be done using sequences. In other words: is there a way to tell a PostgreSQL sequence to use this list X to generate primary keys for my table Y?

One way of doing this would be to use a sequence that contains the index of the last used integer from the list X, call setval() on the sequence, get the next value and try to insert it into my table Y. In case of concurrent requests there will be an error, in which case I need to try with the next value from the list X. I would like to know what other (better) ways there are to achieve what I intend to do.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

謸气贵蔟 2024-12-17 07:44:47

可以像这样工作:

-- DROP SCHEMA x CASCADE;
CREATE SCHEMA x;
CREATE TABLE x.priv_id(seq_id int primary key, id int);

INSERT INTO x.priv_id
SELECT generate_series(1,100,1), (random() * 1000)::int;

CREATE SEQUENCE x.priv_seq;

SELECT id
FROM   x.priv_id
WHERE  seq_id = (SELECT nextval('x.priv_seq'));

要点:

1)创建一个包含两个数字的查找表
- seq_id 从 1 和您的主键开始计数。
- id 是您的序列号(我在这里替换为随机数)。
2) 创建辅助序列。
3) 使用上面的 SELECT 获取您的号码。
您需要子选择,否则将立即返回所有值。

该解决方案提供了 nextval() 必须提供的所有安全性并发。
如果您想确保自定义 ID 是唯一的,请在 priv_id(id) 上创建唯一索引。

Could work like this:

-- DROP SCHEMA x CASCADE;
CREATE SCHEMA x;
CREATE TABLE x.priv_id(seq_id int primary key, id int);

INSERT INTO x.priv_id
SELECT generate_series(1,100,1), (random() * 1000)::int;

CREATE SEQUENCE x.priv_seq;

SELECT id
FROM   x.priv_id
WHERE  seq_id = (SELECT nextval('x.priv_seq'));

Major points:

1) Create a lookup table with two numbers
- seq_id is counting from 1 and your primary key.
- id is your numbers in sequence (I substituted random numbers here).
2) Create a helper sequence.
3) Get your numbers with a SELECT like above.
You need the subselect, or all values will be returned at once.

This solution gives all the security nextval() has to offer for concurrency.
Create a unique index on priv_id(id) if you want to make sure your custom id's are unique.

违心° 2024-12-17 07:44:47

generate_series 可用于生成每个生成的所有数字的列表通过序列:

select * 
from generate_series(1, (select last_value from my_sequence), 1) as x

注意:这假设序列(此处为 my_sequence)从 1 开始并按 1 递增。要改变这些假设,请适当更改参数。

generate_series can be used to produce a list of all numbers every generated by a sequence:

select * 
from generate_series(1, (select last_value from my_sequence), 1) as x

Note: This assumes the sequence (here my_sequence) started at 1 and incremented by 1. To change these assumptions, change the parameters appropriately.

单调的奢华 2024-12-17 07:44:47

提供您自己的一组有效数字的最通用方法是将它们存储在表中,并为其设置外键引用。

这解决了使用您自己的列表的问题,但没有解决从列表中获取下一个数字的问题。为此,您需要编写自己的函数。 (您不能强制 PostgreSQL 序列在您的表上进行操作,而不是使用其内部结构。)不过,这并不是特别难。

另一种经常被忽视的选择(也许有充分的理由)是编写自己的序列。 PostgreSQL 是开源的;您可以根据现有的序列代码编写自己的序列器。编译它,测试它,然后你就可以开始比赛了。 (不过,我不建议这样做。)

The most general way to provide your own set of valid numbers is to store them in a table, and set a foreign key reference to it.

That solves the problem of using your own list, but it doesn't solve the problem of fetching the next number from the list. To do that, you'd need to write your own function. (You can't compel a PostgreSQL sequence to operate on your table instead of using its internals.) It's not particularly hard to do, though.

Another alternative that's often overlooked--perhaps with good reason--is writing your own sequence. PostgreSQL is open source; you can write your own sequencer based on existing sequence code. Compile it, test it, and you're off to the races. (I don't recommend doing that, though.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文