问题描述
通过sql Alchemy将数据插入Postgres表时,我遇到了序列问题。
所有数据都可以正确插入,id BIGSERIAL PRIMARY KEY
列具有所有唯一的值,这很好。
但是,当我查询表的前10/20行等时,id
的值并未按数字顺序递增。序列中存在间隙,很好,这是可以预料的,我的意思是行将随机经过的值不会递增,就像:
id
15
22
16
833
30
etc...
关于这方面,我浏览了很多SO和Postgres论坛帖子,只发现人们谈论序列中存在巨大的序列空白,而不是谈论创建时的错误升序
示例屏幕截图:
表本身已通过标准DDL语句创建,如下所示:
CREATE TABLE IF NOT EXISTS schema.table_name (
id BIGSERIAL NOT NULL,col1 text NOT NULL,col2 JSONB[] NOT NULL,etc....
PRIMARY KEY (id)
);
解决方法
但是当我查询表的前10/20行等时
您的查询没有order by
子句,因此您不必选择表的第一行,而只是选择一组未定义的行。
使用order by
-您会发现序列号确实是以升序分配的(可能带有空格):
select id from ht_data order by id limit 30
为了实际检查序列的顺序,实际上您将需要另一列来存储创建每一行时的时间戳。然后,您可以这样做:
select id from ht_data order by ts limit 30
,
通常,SQL表中没有定义的“顺序”。如果要按特定顺序查看数据,则需要一个ORDER BY
子句:
SELECT *
FROM table_name
ORDER BY id;
对于序列中的间隔,自动递增列的协定通常仅保证每个新生成的id
值具有唯一性,并且在大多数情况下(但不一定总是)会增加。
您怎么可能知道这些值是否“乱序”? SQL表表示无序集。表中唯一显示顺序的是serial
值。
您正在运行的查询没有ORDER BY
。 不保证结果按任何特定顺序排列。。这是关于SQL的非常简单的事实。您想要通过主键或插入顺序排序的SELECT
的结果很好,但不是数据库的工作原理。
您唯一可以确定是否有问题的方法是,如果您有一个单独指定插入顺序的列-例如,您可以有一个创建时间戳。
所有发现的是,SQL履行了不保证顺序的承诺,除非查询明确要求。