想知道 ANSI SQL 标准是否有一种可移植的方法来创建序列对象并从中获取值?
我找不到可移植的方法,但是搜索引擎似乎将 ANSI sql 与 MS SQL 服务器混淆,所以也许我只是错过了它......
想知道 ANSI SQL 标准是否有一种可移植的方法来创建序列对象并从中获取值?
我找不到可移植的方法,但是搜索引擎似乎将 ANSI sql 与 MS SQL 服务器混淆,所以也许我只是错过了它......
尝试将 auto_increment 添加到现有列
ALTER TABLE table_name ALTER COLUMN id_column SET DEFAULT nextval('table_id_column_seq');
尝试1:
CREATE SEQUENCE table_id_column_seq AS integer START 1 OWNED BY table.id_column;
错误:
错误:序列必须与其链接的表具有相同的所有者
尝试2:
CREATE SEQUENCE table_id_column_seq AS integer START 1 OWNED TO postgres;
错误:
ERROR: syntax error at or near "integer"
LINE 1: CREATE SEQUENCE table_id_column_seq integer START 1...
^
应该是这样吗?
例如,我可以使用相同的序列在两个单独的表上生成主键吗?
CREATE TABLE IF NOT EXISTS public."user_Registered"
(
id integer NOT NULL DEFAULT nextval('user_id_seq'::regclass),
email character varying COLLATE pg_catalog."default" NOT NULL,
CONSTRAINT "PK_1" PRIMARY KEY (id),
CONSTRAINT "UQ_1" UNIQUE (email)
)
CREATE TABLE IF NOT EXISTS public."user_Applicant"
(
id integer NOT NULL DEFAULT nextval('user_id_seq'::regclass),
email character varying COLLATE pg_catalog."default" NOT NULL,
CONSTRAINT "PK_2" PRIMARY KEY (id),
CONSTRAINT "UQ_2" UNIQUE (email)
)
在我的示例中,注册用户拥有的数据不仅仅是电子邮件,我无法将其存储在同一个表中并在他们注册时填充。所以我的计划是将它们保存在申请表中,然后将它们移动到注册表中,但我想保留 ID。
我有以下两个表来存储用户及其地址。我有一个与我接收和保存用户数据的顺序有关的问题。起初,用户将只提供地址,然后被定向到外部服务。要打开此服务,我需要提供我的内部用户 ID。该服务会验证他们的电子邮件地址并将回复发送给我。
CREATE TABLE IF NOT EXISTS public."user"
(
id integer NOT NULL DEFAULT nextval('user_id_seq'::regclass),
email character varying COLLATE pg_catalog."default" NOT NULL,
CONSTRAINT "PK_cace4a159ff9f2512dd42373760" PRIMARY KEY (id),
CONSTRAINT "UQ_e12875dfb3b1d92d7d7c5377e22" UNIQUE (email)
)
CREATE TABLE IF NOT EXISTS public.adresses
(
id integer NOT NULL DEFAULT nextval('address_id_seq'::regclass),
address character varying COLLATE pg_catalog."default" NOT NULL,
"userId" integer,
CONSTRAINT "PK_bec464dd8d54c39c54fd32e2334" PRIMARY KEY (id),
CONSTRAINT "FK_35472b1fe48b6330cd349709564" FOREIGN KEY ("userId")
REFERENCES public."user" (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
)
我试图弄清楚当相应的序列在 Postgres 中溢出时表插入的行为。为了测试这一点,我创建了一个表
CREATE TABLE t1(
id SERIAL
);
这创建了一个相应的序列
select pg_get_serial_sequence('t1', 'id');
pg_get_serial_sequence
------------------------
public.t1_id_seq
(1 row)
我手动编辑了序列并设置了一个最大值
alter sequence t1_id_seq MAXVALUE 5;
在这一点上,我预计一旦序列达到最大值,我将无法插入到表中。但我看到我仍然可以插入到表格中。
insert into t1 select * from generate_series(10,100);
INSERT 0 91
并且序列 nextval 设置为 1
select * from nextval('t1_id_seq');
nextval
---------
1
(1 row)
当序列溢出时,表插入不应该失败吗?为什么在这种情况下序列没有溢出?
我在 PostgreSQL 13 中有一个简单的表格,如下所示:
table name: newtable1
field type
----- ----
Seq bigserial
code varchar
Seq
是主键(自增)
Code
是唯一键索引
Insert Into newtable (Code) Values ('001') On Conflict(Code) Do Nothing --> Seq value is 1
Insert Into newtable (Code) Values ('001') On Conflict(Code) Do Nothing
Insert Into newtable (Code) Values ('001') On Conflict(Code) Do Nothing
Insert Into newtable (Code) Values ('002') On Conflict(Code) Do Nothing --> Seq value is 4
为什么Seq值不断增加?
如果成功插入,有没有办法只增加 Seq 值?
希望有人能澄清本文的一部分“可扩展的增量数据聚合”和相应的问题。
假设 Postgres 10 及更高版本。
在 Postgres 10 中,您可以使用 pg_sequence_last_value 函数来检查最近发布的序列号。但是,简单地将所有事件聚合到最近的序列值是不安全的。可能仍有正在进行的事件表写入被分配较低的序列值,但在聚合运行时尚不可见。
是否有 pg_sequence_last_value 的替代品可以保证正确的 seq id?
在具有 BIGSERIAL id 的表(称为事件)中,是否有首选方法来获取最新的 seq id 以用于聚合目的?如果在不同的事务中有待处理的插入(它们将具有更高的序列 ID)并在后续运行中被拾取,那很好。
目标是使用 seq id 在已提交的插入上运行聚合(增量汇总)。
以下三种方法是否保证为已提交的插入返回最新的 seq id 并避免与 pg_sequence_last_value 相关的文章中提到的陷阱?
还有其他技术可以建议吗?
SELECT max(id) FROM events;
SELECT last_value FROM pg_sequences WHERE sequencename='events_id_seq';
SELECT id FROM events ORDER BY id DESC LIMIT 1;
假设read committed
隔离级别
我正在尝试通过以下方式创建序列:
create sequence some_seq start with (select max(id) + 1 from some_table);
但我收到以下错误:
ERROR: syntax error at or near "("
我也尝试过这种方法:
DO $$
DECLARE
min_seq_value int8 := (select max(id) + 1 from some_table);
BEGIN
create sequence some_seq start with min_seq_value;
END; $$;
但它给了我:
ERROR: syntax error at or near "min_seq_value"
它似乎很基本,但我无法让它工作。有任何想法吗?
谢谢!
我正在创建一个聊天应用程序,我会将所有对话和用户的聊天消息保存在一个分区(在 convo ids 上)的 BRIN 索引表中。当我的服务器想要存储新消息时,它必须知道每个对话的最后一条消息的序列号。可能会有很多对话,那么为数据库中的每个对话动态生成一个序列(CREATE SEQUENCE 序列)可以吗?
我将使用带有 Nodejs 网络服务器集群和 REDIS 实例的数据库。从语义上讲,redis 位于 nodejs 和 Postgres db 之间。我的第二个想法是代替序列,我将创建一个表来保存每个 convo(两列)的计数器,将计数器加载到 redis 中,并在聊天时锁定行,在那里递增并定期写回。
哪个更好,这些都好吗?谢谢!
编辑
消息表是基于 convo id 和消息号索引的多列 BRIN。并且两列没有pk,也没有唯一约束。可能存在差距,甚至可能存在重复(由于 redis INCR 的原子性,这不太可能,因为它将是唯一的实例)(另一个重要点)
我必须详细说明。我收到两个回复,告诉我只需为数据库中的每条消息制作一个序列。问题在于布林指数的长期有效性。这就是我在问题中写它的原因,因为它很重要。如果你不知道 brin 指数是如何工作的,请查一下。本质上它是一个范围索引。现在,如果您对所有消息进行一个序列,您会看到会发生什么。对于 brin,消息编号/id 不会添加任何信息,因为随着时间的推移,所有对话的所有消息 id 将介于一个相对较小的数字和最后一个序列值之间。我认为那会大大降低选择速度。这是聊天应用程序。我将不得不在登录时查询未发送的消息。并且不要告诉我使用 btree 甚至不要回答谢谢:D
我曾考虑过 UUID,但出于与上述相同的原因,这不会有帮助。
编辑 2
我现在明白生成序列是一个坏主意。所以剩下的是第二个选项,或者可能是一个序列建议,以防您争论它对查询性能的影响。
我有一个数据库,它既具有与表唯一 ID 相关的序列,又具有“独立”但具有值。
我需要知道哪些是真正使用的,但我不是数据库上运行的每个过程的所有者。
有什么方法可以知道上次使用 Postgres 序列的时间?