当前位置: 首页 > news >正文

如何设置PostgreSQL表字段为自增主键

目录

  • 前言
  • 设置自增主键
  • 去重
  • 表复制

前言

  1. 最近公司的项目遇到多次这样的需求:需要将原表符合条件的记录复制到新表,但原表的主键字段在新表中需转为普通字段。这篇博客主要介绍如何为新表设置自增主键字段。
  2. 还有一个是如何利用窗口函数将表中某几个字段值重复的记录只保留一条有效,其余重复记录作废或者删除,这个需求也是最近经常遇到

设置自增主键

  1. 我们经常碰到这样的场景,通过create table as select xxx from table where xx需要将原表符合条件的记录复制到新表,值得注意的是这样新创建的表,并没有将表结构复制到新表,原表的主键字段在新表中是一个普通字段

  2. 首先,先确保当前表中没有主键以及当前要设置主键字段的字段类型。

  3. 第一步,要在pg数据库中创建一个序列,序列是PostgreSQL实现自增功能的核心数据库对象,用处就是字段值可以设置为由已创建的序列提供,每次序列可以自增生成一个唯一的整数,我们可以设置序列的初始值和步长

    	-- 序列名称最好以表名_id_sq
    CREATE SEQUENCE [IF NOT EXISTS] sequence_name[ INCREMENT BY increment ][ START WITH start ][ ... ] -- 其他参数如 MINVALUE, MAXVALUE, CACHE, CYCLE
    

    因此,我们首先要知道当前要设置为主键字段的最大值,如果当前字段的最大值为100,那么序列的初始值就要设为101,步长默认是1,一般不需要设置步长

    -- 先查出当前字段的最大值
    select max(id) from table_name
    -- 创建序列,指定初始值和步长
    CREATE SEQUENCE table_name_id_seq
    START WITH 100
    INCREMENT BY 1;
    

    当然,如果序列创建错了,也可以直接修改已存在序列地初始值和步长

    -- 修改序列初始值为500
    ALTER SEQUENCE table_name_id_seq RESTART WITH 500;
    -- 修改序列步长为5
    ALTER SEQUENCE table_name_id_seq INCREMENT BY 5;
    
  4. 下一步,就是指定字段的数值来源为已创建的序列,由序列提供字段数值

    ALTER TABLE table_name ALTER COLUMN id SET DEFAULT nextval('table_name_id_seq ');
    
  5. 最后,为字段添加主键约束即可

    ALTER TABLE table_name ADD PRIMARY KEY (id);
    

去重

  • 我们经常碰到的数据库需求就是根据某几个字段,对重复记录去重,只保留一条,其余作废(valid=0)或者删除,在pg数据库,一般我们通过窗口函数ROW_NUMBER()实现这个功能

    UPDATE table_name
    SET valid = '0'
    WHERE ctid IN (SELECT ctidFROM (SELECTctid,ROW_NUMBER() OVER (PARTITION BY field1, field2, field3 ORDER BY ctid) AS rnFROM table_name) AS ranked_rowsWHERE rn > 1  -- 将过滤条件放在正确的外层
    );
    
  • 这段sql核心是通过窗口函数ROW_NUMBER()将同组(重复记录集合)的记录编号,然后保留编号最小的一个,编号>1的记录作废来实现去重的目的

    SELECT ctid,
    ROW_NUMBER() OVER (PARTITION BY field1, field2, field3 ORDER BY ctid) AS rn FROM table_name
    
  • ROW_NUMBER() OVER (...) AS rn​​: 这行代码是核心。ROW_NUMBER()是一个窗口函数,它会为每一行分配一个唯一的序号

  • PARTITION BY field1, field2, field3​​: PARTITION BY子句定义了如何将数据分组。这里表示​​将 field1, field2, field3这三个字段完全相同的记录归为同一组​​。窗口函数会在每个组内独立进行编号

  • ORDER BY ctid​​: 这指定了在每个分组内,记录按 ctid排序。ctid是 PostgreSQL 系统列,代表行的物理位置(文件号和页内的元组索引),可以理解为每行的唯一物理标识。按此排序意味着​​在同一分组内,先插入的行(理论上ctid更小)会获得更小的行号

表复制

  • 仅复制表结构(不复制数据)
-- 基本用法,复制列定义(包括NOT NULL约束)
CREATE TABLE new_table (LIKE old_table);-- 扩展用法,复制包括索引、约束等更多对象
CREATE TABLE new_table (LIKE old_table INCLUDING ALL);
  • 复制表结构及其所有数据
    记得要注意,表的约束、索引等并没有复制,需要手动重新添加
-- 标准语法
CREATE TABLE new_table AS SELECT * FROM old_table;-- 简化语法,效果相同
CREATE TABLE new_table AS TABLE old_table;
http://www.dtcms.com/a/473951.html

相关文章:

  • 排版工具:也说Markdown的使用方法
  • 分销网站建站wordpress调用推荐文章代码
  • 数据湖Hudi-读取流程可视化
  • 智能环境感知屏幕自适应系统:原理、架构与实现
  • 中卫网站制作公司公司网站seo怎么做
  • Python高效搜索实现:从数据海洋到精准信息的智能导航
  • 安安网站建设优惠的网站快排公司电话
  • Elasticsearch 备份:snapshot 镜像使用篇
  • 10月12日星期天今日早报简报微语报早读
  • 著名建筑网站网站建设市场价
  • MySQL快速构建主从(基于GTID)
  • 感知机:单层,多层(二分类,多分类)
  • 宁波网站建设服务公司电话俄乌局势最新进展
  • python进阶_Day6
  • 网站pv uv统计wordpress 破解主题下载地址
  • 全参数与PEFT深度剖析
  • 记忆翻牌游戏
  • 自己做的网站如何让别人访问织梦帝国wordpress
  • Linux -程序地址空间
  • (Spring)@PathVariable 与 @RequestParam 区别与应用
  • SpringAI从入门到精通 (2)
  • Linux 12mybash的实现
  • K8s YAML 文件详解:从语法到实战编写指南
  • 社区版Idea怎么创建Spring Boot项目?Selected Java version 17 is not supported. 问题解决
  • 益阳市 网站建设电子商务网站建设的主要风险
  • SpringBootRemotePowershellAdmin:开箱即用的 Windows远程运维开源工具
  • 插槽vue/react
  • 对vue生命周期的理解
  • 2017民非单位年检那个网站做黄山旅游攻略景点必去
  • [笔记 自用]CAN总线通信配置