【问题标题】:Primary Key assignment in PostgresPostgres 中的主键分配
【发布时间】:2015-07-31 23:12:03
【问题描述】:

我的 postgres 数据库中有表 tmp,其中包含大约 1.39 亿条记录。我正在尝试将列col1col2col3 移动到另一个名为r4a 的表的col1col2col3。我用这个查询创建了表r4a

CREATE TABLE r4a(
    gid serial NOT NULL,
    col1 double precision,
    col2 double precision,
    col3 double precision,
    the_geom geometry,
    CONSTRAINT r4a_pkey PRIMARY KEY (gid));

我在查询中创建了这个插入以填充 r4a 中的字段:

INSERT INTO r4a (col1,col2,col3)
SELECT col1, col2, col3
FROM tmp
limit 500;

它使用范围为 [14816024-14816523] 的数字填充 gid [PK] serial 列。

它如何确定也限制查询的 500 条记录?
是选择导入行[14816024-14816523]还是只是随意分配数字?

理想情况下,我希望主键从 1 开始并向上计数。作为 postgres 的新手并且拥有如此大的(在我看来)表,我想确保我了解发生了什么。

【问题讨论】:

  • 在大多数数据库中,使用limittop 或类似的东西而不指定任何order by 子句将返回一组随机的行。可能是受影响的行按某种顺序(通常按插入顺序),但不能保证。如果您想要一组特定的行,则必须指定它。由于我不熟悉 Postgresql 的具体细节,因此我不会将其发布为答案,但我敢打赌它也适用于 PG。
  • 我如何查询我将查询更改为仅移动前 500 行?
  • 我不知道 Postgresqls 串行类型的机制,所以恐怕帮不了你。

标签: sql postgresql primary-key sql-insert


【解决方案1】:

为 Serial 列选择的值与从另一个表中选择的值无关 - 尽管没有 ORDER BY 子句,这些将是一个完全任意的样本,碰巧很容易检索。

Serial 列实际上是一个定义了默认值的 Integer 列,它从称为序列的特殊对象中获取下一个值。 Sequence 是一个独立于事务的计数器,从 1 开始,永远不会回滚,即使读取并丢弃了一个值。

因此,如果您的序列值如此之高,那是因为您已经从其中请求了许多值 - 可能是在您后来删除的插入中、您回滚的事务中,或者在中途因错误而中止的语句中。

您可以使用setval() 函数手动重置序列;一个有用的配方是setval(pg_get_serial_sequence('r4a', 'gid'), 1) 但请记住,这不会关心表中已经插入了哪些值,因此如果它生成一个已经存在的 ID,您将得到重复的键错误(重复插入将继续增加序列并最终生成一个尚未使用的 ID,但这不是您希望生产代码依赖的东西!)。

【讨论】:

    猜你喜欢
    • 2021-11-03
    • 1970-01-01
    • 2021-05-18
    • 1970-01-01
    • 1970-01-01
    • 2021-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多