PostGres常用sql锦集(持续更新中,内容会越来越多)

PostgreSQL - 基础入门 它是开源的,其源代码是免费提供的。它是用PHP编写的PostgreSQL的基于Web的管理工具。PostgreSQL是跨平台的,可以在许多操作系统上运行,如Linux,FreeBSD,OS X,Solaris和Microsoft Windows等。它是一个命令行工具,也是管理PostgreSQL的主要工具。左外连接返回从“ON”条件中指定的左侧表中的所有行,只返回满足条件的另一个表中的行。右外连接返回从“ON”条件中指定的右侧表中的所有行,只返回满足条件的另一个表中的行。右边的空格填充到相等大小的字符。 阅读详情

POSTGRES常用sql示例(持续更新中,搞个示例,忘了语法可以查一下)

psql常用命令

1、使用postgres超级用户登录: ./psql -U postgres
2、创建imsdb这个数据库: create database imsdb [owner rcb]
3、赋予rcb用户所有权限: grant all privileges on database imsdb to rcb
4、如果创建时未设置owner,可以更改: alter database imsdb owner to rcb
5、查看数据库: \l命令查看所有数据库
6、连接数据库: \c imsdb 连接imsdb这个数据库
7、显示所有的schema: \dn
8、显示所有的用户: \du
9、显示表的权限分配情况: \dp
10、显示当前的模式: show search_path
11、更改模式: set search_path to myschema
12、已列的形式展示: \x (当不想列展示时,再次\x即可)
13、查看数据存储目录: show data_directory;
14、 查看函数定义:select prosrc from pg_proc where proname =‘函数名称’;
15、 查看函数定义更简便的方法: \sf 函数名 ## sf 是 show function’s definition的简称
16、 查看表结构: \d 表名 或 \d+ 表名
17、 修改数据库密码:alter user postgres with password ‘123456’; 修改密码为123456

pg数据dump示例

#! /bin/bash
export PGPASSWORD='123456';pg_dump -U cbdca -h 10.33.65.9 -p 5432 -c -C -d cbdca -f /app/dbbak/cbdca/cbdca-20220718/cbdca-all.sql
export PGPASSWORD='123456';pg_dump -U cbdca -h 10.33.65.9 -p 5432 -d cbdca -t acs_config -f /app/dbbak/cbdca/cbdca-20220718/acs_config.sql
export PGPASSWORD='123456';pg_dump -U cbdca -h 10.33.65.9 -p 5432 -d cbdca -t acs_pic_server_bind_info -f /app/dbbak/cbdca/cbdca-20220718/acs_pic_server_bind_info.sql


开启日志打印


PostgreSQL 日志配置在 $PGDATA/postgresql.conf ;修改并保存配置后需要重载配置 select pg_reload_conf(); 或重启服务后生效

一般错误跟踪
logging_collector = on     # 开启日志采集
log_destination = 'stderr' # 日志输出格式,配置为 csvlog - 输出到csv文件:
log_directory = 'pg_log'   # 可配置为:$PGDATA的相对路径或绝对路径
log_filename = 'postgresql-%Y-%m-%d.log' # 输出日志文件名格式
log_filename = 'postgresql-%a.log' # 这是默认格式,%a代表星期
log_rotation_age = 1440             # minute,多长时间创建新的文件记录日志。0 表示禁扩展。
log_rotation_size = 10240           # kb,文件多大后创建新的文件记录日志。0 表示禁扩展。
log_truncate_on_rotation = on       # 可重用同名日志文件
log_min_messages = info   



# 监控慢sql日志
log_statement = all  # 需设置跟踪所有语句,否则只能跟踪出错信息,设置跟踪的语句类型,有4种类型:none(默认), ddl, mod, all。跟踪所有语句时可设置为 "all"。 
log_min_duration_statement = 5000   # milliseconds,记录执行5秒及以上的语句,跟踪慢查询语句,单位为毫秒。如设置 5000,表示日志将记录执行5秒以上的SQL语句。-1 is disabled, 0 logs all statements
log_checkpoints = on
log_connections = on
log_disconnections = on
log_duration = on
log_error_verbosity = verbose   
log_line_prefix = '%m'
# 监控数据库中长时间的锁
log_lock_waits = on
# 记录DDL操作
log_statement = 'ddl'   #可以是all
deadlock_timeout = 5s  ##模拟死锁期间,可以将值调大,方便观察,生产环境不要设置太大的值



# 例如查询执行时间超过1秒的SQL  
select * from pg_stat_activity where state<>'idle' and now()-query_start > interval '1 s' order by query_start ; 


##查看日志文件和目录
show log_directory;
show log_filename;


删除数据库

1 删除数据库:
DROP DATABASE [ IF EXISTS ] name

2 创建数据库和用户
drop database if exists artemis;
create user artemis with password '123qaz!@#';
create database artemis with template = template0 encoding = 'UTF8' lc_collate = 'en_US.UTF8' lc_ctype = 'en_US.UTF8';
alter database artemis owner to artemis;
grant all on database artemis to artemis;

导出查询数据方式

1 使用psql -U xxx -d xxx命名进入交互界面,输入下属命令并回车,可以将输出重定向到person.txt文件
\o /home/hik/lyc/person.txt
2 输入查询语句,这样,满足查询条件的数据会被定向输出到文件:/home/hik/lyc/person.txt:
  select * from person where is_delete = 0;

查看所有表,序列

查看所有表:
select  * from   pg_tables  where schemaname = 'public';

查看所有序列:
select * from pg_class where relkind='S'

--查看数据库:
select * from pg_database;

--查看表空间
select * from pg_tablespace;

--查看语言
select * from pg_language;

--查看角色用户
select * from pg_user;

select * from pg_shadow;

select * from pg_roles;

--查看会话进程
select * from pg_stat_activity;

--查看表
SELECT * FROM pg_tables where schemaname = 'public';

--查看表字段
select * from information_schema.columns where table_schema = 'public' and table_name = 'noip_user';

--查看视图
select * from pg_views where schemaname = 'public';

select * from information_schema.views where table_schema = 'public';

--查看触发器
select * from information_schema.triggers;

--查看序列
select * from information_schema.sequences where sequence_schema = 'public';

--查看约束
select * from pg_constraint where contype = 'p';

注意: --u unique,p primary,f foreign,c check,t trigger,x exclusion

select a.relname as table_name,b.conname as constraint_name,b.contype as constraint_type from pg_class a,pg_constraint b where a.oid = b.conrelid and a.relname = 'cc';

--查看索引
select * from pg_index ;

--查看表大小(不含索引等信息)
select pg_relation_size('noip_user'); 
select pg_size_pretty(pg_relation_size('noip_user'));

--查看DB大小
select pg_size_pretty(pg_database_size('noip')); 

查看表信息

--- 查看表中各个字段类型

SELECT
    format_type (A .atttypid, A .atttypmod) AS TYPE,
    A .attname AS NAME
FROM
    pg_class AS C,
    pg_attribute AS A
WHERE
    C .relname = '你的表名'
AND A .attrelid = C .oid
AND A .attnum > 0;

删除数据库中所有的表,进入欲删除表的数据库,执行下列存储过程

DO $$ DECLARE
    r RECORD;
BEGIN
    -- if the schema you operate on is not"current", you will want to
    -- replace current_schema() in query with 'schematodeletetablesfrom'
    -- *and* update the generate 'DROP...' accordingly.
    FOR r IN (SELECT tablename FROM pg_tables WHERE schemaname = current_schema()) LOOP
        EXECUTE 'DROP TABLE IF EXISTS ' || quote_ident(r.tablename) || ' CASCADE';
    END LOOP;
END $$;

修改表,序列的owner:


ALTER TABLE public.temperature_warn_event OWNER TO postgres;
GRANT ALL ON TABLE public.temperature_warn_event TO postgres;
alter  sequence  public.seq_device_type_id owner to postgres;

更换字段引用的序列示例:


alter table tpe_event alter column id drop default; 
create sequence seq_tpe_event_id  minvalue 1 maxvalue 9223372036854775807 start with 1 cycle; 
select nextval('seq_tpe_event_id');
select setval('seq_tpe_event_id', '291305');
alter table tpe_event alter column id set default nextval('seq_tpe_event_id');

创建表,使用自增主键示例

DROP SEQUENCE  IF EXISTS  seq_device_type_id;
create sequence  public.seq_device_type_id  minvalue 1 maxvalue 9223372036854775807 start with 1 cycle;
alter  sequence  public.seq_device_type_id owner to postgres;
DROP TABLE IF EXISTS device_type;
CREATE TABLE "public"."device_type" (
  id int4 NOT NULL default nextval('seq_device_type_id'::regclass),
  device_type int4 not null,
  device_type_name varchar(64),
  device_sub_type int4 not null,
  device_sub_type_name varchar(64),
  device_model varchar not null,
  device_model_type int4 not null,
  create_time timestamp not null default now(),
  update_time timestamp(0) not null default now(), --精度保存到秒,默认是毫秒 
  CONSTRAINT device_type_pkey PRIMARY KEY (id)
) WITH (
    OIDS = FALSE
);

alter table public.device_type owner to postgres;

COMMENT ON TABLE device_type IS '设备类型表';
------------------------------
COMMENT ON COLUMN device_type.id IS '主键';
------------------------------
COMMENT ON COLUMN device_type.device_type IS '设备大类, 0: 代表门禁设备';
COMMENT ON COLUMN device_type.device_type_name IS '设备大类名称, 比如: 门禁设备';
------------------------------
COMMENT ON COLUMN device_type.device_sub_type IS '设备子类, 比如门口机, 门口机也属于门禁设备';
COMMENT ON COLUMN device_type.device_sub_type_name IS '设备子类名称, 比如门口机';
------------------------------
COMMENT ON COLUMN device_type.device_model IS '设备出场型号, 比如: DS-KH9300-A';
COMMENT ON COLUMN device_type.device_model_type IS '设备型号类型,0: 完整型号, 1: 设备型号前缀';

insert into device_type(id, device_type, device_type_name, device_sub_type, device_sub_type_name, device_model, device_model_type, create_time) values (nextval('seq_device_type_id'), 0, '门禁设备',  10, '门口机', 'DS-K1T671MI', 0,  now());

字段相关操作

---修改字段类型,从int4改为int8
ALTER TABLE event ALTER COLUMN event_id TYPE int8 USING event_id::int4;


------修改字段长度
alter table nb_device alter column  cmd_json  type varchar(1024);

---新增字段
alter table event add column house_id varchar(36);

---修改字段名称
ALTER TABLE event rename event_id to id;

----移除非空限制
alter table person_house alter COLUMN person_house_type drop not null;

------- 删除字段
ALTER TABLE users DROP COLUMN id_card CASCADE; 

alter table tb_gas_cmd_record add column if not exists batch_id varchar(32) default '';

创建索引示例


--- 引入扩展
CREATE EXTENSION pg_trgm;

----采用gin_trgm_ops建立索引完成,但对于联合索引,gin_trgm_ops将合并成一个字符串查询, 例如
CREATE INDEX INDEX_BILL_RECORDING_GIN ON bill_recording using gin ((bill_name || ' ' || payment_account || ' ' || account_id) gin_trgm_ops);

---采用pg_trgm 建立gin索引
CREATE INDEX tpe_event_gin_index_parking_name     ON tpe_event USING gin ((parking_name) gin_trgm_ops);

---创建btree索引
CREATE INDEX nb_device_btree_index_ys_device_id             ON nb_device USING btree (ys_device_id);

-- gin联合索引占用空间比btree大,索引数量与列数有关,执行过程中会锁表,为不影响插入,修改等操作,可使用CONCURRENTLY不锁表建立索引
CREATE INDEX CONCURRENTLY index_name ON table_name USING gin ( UPPER ( first_name ), UPPER ( last_name ), UPPER ( email ), UPPER(username));

---有时候需要建立联合索引,但同时不同的列不愿意合成一个字段,这个时候可以gin建立联合索引, 先修改默认pg_opclass
UPDATE pg_opclass SET opcdefault = TRUE WHERE opcname = 'gin_trgm_ops';

----补充主键
alter table person add constraint person_pkey primary key(id);
ALTER TABLE "person " ADD CONSTRAINT "person_pkey" IF NOT EXISTS  PRIMARY KEY ("id");

----- 添加唯一性索引
alter table tbl_unique_index add constraint uk_tbl_unique_index_b unique(b);

  CREATE INDEX if not exists idx_pu_tian_shp_mzguid ON pu_tian_shp (mzguid);

----- 删除索引语句:
DROP INDEX unique_all_column

Geometry类型操作
--- 创建视图pt_yw,并授权给test_user
 CREATE SCHEMA IF NOT EXISTS pt_yw AUTHORIZATION  test_user;
--- 插入多边形数据
 CREATE TABLE IF NOT EXISTS  "pt_yw"."my_geo" (
          "id" int8 ,
          "geom",
          constraint "my_geo_pkey" primary key ("id")
        ) ;
insert into "pt_yw".my_geo(id, geom) values(1, 'MULTIPOINT((0 0), (1 1 ), (2 2 ))');
insert into "pt_yw".my_geo(id, geom) values(2,   'MULTILINESTRING ((10 10, 20 20, 10 40), (40 40, 30 30, 40 20, 30 10))');
select  ST_AsText(geom)  from pt_yw.my_geo;
        
查看某个表的索引使用情况
select 
    relname, indexrelname, idx_scan, idx_tup_read, idx_tup_fetch 
from 
    pg_stat_user_indexes 
where
    relname = table_name 
order by 
    idx_scan asc, idx_tup_read asc, idx_tup_fetch asc;

插入数据

将表dev_user_copy1 中的数据插入到dev_user中
insert into dev_user(id, name, pwd, company, job ,email) select id, name, pwd, company, job ,email from dev_user_copy1 where id not in (select id from dev_user)

--插入数据,id冲突会报错
INSERT INTO t_system_config (id, name, value) VALUES ('mapType', '地图类型', '10');
--插入数据,id冲突不会报错
insert into t_system_config(id,name,value) ( select 'mapType', '地图类型', '10' from t_system_config
   where not exists(select * from t_system_config where id='mapType'));
或者:
insert into t_system_config(id,name,value) ( select 'mapType', '地图类型', '10' from t_system_config
   where not exists(select * from t_system_config where id='mapType') limit 1);


情空表中数据
truncate  table;比如表名是account, 则 truncate  account;

修改名称

--- 修改表名
alter table t_announcement_info rename to announcement_info;
alter table t_advise rename to advise_info;

常用语句举例

## 给district表的create_time增加一个随机值,消除重复,语句中20000是district表的记录总数
select count(*) from district;
update district  dis set create_time = create_time + (1/20000 ::float) * a.num *(interval '5' second) from (select  id, row_number() over() as num from district) a   where dis.id = a.id;


----- update from语句
update nb_event set handle_result = h.handle_result, handle_suggestion = h.handle_suggestion,   handle_person = h.handle_person, handle_time = h.handle_time, extend = h.extend from nb_event_handle h where nb_event .id = h.event_id;


数据库磁盘占用统计

统计数据库中各表占用大小
SELECT
    table_schema || '.' || table_name AS table_full_name,
    pg_size_pretty(pg_total_relation_size('"' || table_schema || '"."' || table_name || '"')) AS size
FROM information_schema.tables
ORDER BY
    pg_total_relation_size('"' || table_schema || '"."' || table_name || '"') desc;
统计各数据库占用磁盘大小:
SELECT d.datname AS Name,  pg_catalog.pg_get_userbyid(d.datdba) AS Owner,
    CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')
        THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))
        ELSE 'No Access'
    END AS SIZE
FROM pg_catalog.pg_database d
    ORDER BY
    CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')
        THEN pg_catalog.pg_database_size(d.datname)
        ELSE NULL
    END DESC -- nulls first
    LIMIT 20;

数据库状态

查看数据库连接进程 每个服务器进程一行,显示数据库OID、数据库名、进程ID、客户端地址、客户端端口、最近查询时间、进程开始时间
select datid, datname, pid, client_addr, client_port, query_start, backend_start from pg_stat_activity;

select * from pg_stat_activity;
查看数据库使用情况 每个数据库一行,显示数据库OID、数据库名、数据库连接进程数、提交的事务总数、回滚总数、读取磁盘块的总数,缓冲区命中的总数
select * from pg_stat_database;
列出数据库中的自定义函数
//列出函数名称,返回类型,入参数量
SELECT
  pg_proc.proname AS "函数名称",
  pg_type.typname AS "返回值数据类型",
  pg_proc.pronargs AS "参数个数"
FROM
  pg_proc
    JOIN pg_type
   ON (pg_proc.prorettype = pg_type.oid)
WHERE
  pg_type.typname != 'void'
  AND pronamespace = (SELECT pg_namespace.oid FROM pg_namespace WHERE nspname = 'public');
 
 //列出所有字段 
SELECT *
FROM
  pg_proc
    JOIN pg_type
   ON (pg_proc.prorettype = pg_type.oid)
WHERE
  pg_type.typname != 'void'
  AND pronamespace = (SELECT pg_namespace.oid FROM pg_namespace WHERE nspname = 'public');

RANGE 分区函数使用示例

DROP TABLE IF EXISTS  measurement;
CREATE TABLE measurement (
    id int8 null,
    logdate   timestamp not null
    
) PARTITION BY RANGE (logdate);

--创建普通分区

create table m_20230519 partition of measurement for values from ('2023-05-19 00:00:00') to ('2023-05-19 23:59:59');
alter table m_20230519  add constraint  m_20230519_pkey primary key (id);


create table m_20230520 partition of measurement for values from ('2023-05-20 00:00:00') to ('2023-05-20 23:59:59');
alter table m_20230520  add constraint  m_20230520_pkey primary key (id);

-- 创建默认分区
create table m_default  partition of  measurement default;

-- 删除默认分区
ALTER TABLE measurement DETACH PARTITION m_default;


-- 绑定默认分区
alter table measurement attach partition m_default default;


-- 插入数据源
insert into measurement (id, logdate) values (1, now());

insert into measurement (id, logdate) values (2, '2023-05-25');


insert into measurement (id, logdate) values (2, '2023-05-20');




在PostgreSQL中,可以通过查询系统表pg_partitions来判断表是否分区。以下是一个示例查询:
SELECT * FROM pg_partitions WHERE parent_table = 'your_table_name';
这将返回指定表的所有分区信息。如果返回结果为空,则说明该表没有分区。您也可以通过查看表的定义来确定是否为分区表,例如:

SELECT relkind FROM pg_class WHERE relname = 'your_table_name';
如果返回的relkind为 ‘p’,则表示该表是一个分区表。




select * from pg_inherits where cast(cast(inhparent as regclass) as text) = 'measurement' and  cast(cast(inhrelid as regclass) as text) = 'm_default';

select * from pg_inherits where cast(cast(inhparent as regclass) as text) = 'measurement';


select c.relname from pg_class c join pg_inherits i on i.inhrelid = c.oid join pg_class d on d.oid = i.inhparent where d.relname = 'measurement';

关于锁
PostgreSQL中主要有两种锁,一个表锁一个行锁
PostgreSQL中也提供了页锁,咨询锁,But,这个不需要关注,他是为了锁的完整性

表锁显而易见,就是锁住整张表。表锁也分为很多中模式。表锁的模式很多,其中最核心的两个:ACCESS SHARE:共享锁(读锁),读读操作不阻塞,但是不允许出现写操作并行。ACCESS EXCLUSIVE:互斥锁(写锁),无论什么操作进来,都阻塞。

表锁使用示例:
begin;
-- 基于默认的ACCESS EXCLUSIVE锁住test表
lock test in ACCESS SHARE mode;
-- 操作
select * from test;
-- 提交事务,表锁释放
commit;

注意,表锁语法为 lock table [only] [表名] in [xxx]  mode;  [xxx]的可选值为: ROW SHARE , ROW EXCLUSIVE 
SHARE , exclusive ,ACCESS SHARE  , ACCESS EXCLUSIVE ,SHARE ROW EXCLUSIVE , SHARE update exclusive
比如: lock table only "event" in SHARE update EXCLUSIVE  mode;  ## event是表名


PostgreSQL的行锁和MySQL的基本是一模一样的,基于select for update就可以指定行锁。MySQL中有一个概念,for update时,如果select的查询没有命中索引,可能会锁表。PostgerSQL有个特点,一般情况,在select的查询没有命中索引时,他不一定会锁表,依然会实现行锁。PostgreSQL的行锁,就玩俩,一个for update,一个for share。在开启事务之后,直接执行select * from table where 条件 for update;

行锁使用示例:
-- 先开启事务
begin;
-- 基于for update 锁住id为3的数据
select * from test where id = 3 for update;
update test set name = 'v1' where id = 3;
-- 提交事务,锁释放
commit;

jdbc连接工具类

package com.hikvision.data.modules.backup;

import com.hikvision.data.core.support.logger.LogFactory;
import org.slf4j.Logger;

import java.sql.*;

public class PgTool {

    private static Logger logger = LogFactory.getLogger(PgTool.class);

    public Connection getConnection(String ip, Integer port, String dbName, String username, String password) {
        String url = "jdbc:postgresql://" + ip + ":" + port + "/" + dbName +
                "?useUnicode=true&characterEncoding=utf-8&useLegacyDatetimeCode=false&serverTimezone=UTC";

        Connection connection = null;
        try {
            Class.forName("org.postgresql.Driver").newInstance();
            connection = DriverManager.getConnection(url, username, password);
        } catch (InstantiationException e) {
           logger.error("", e);
        } catch (IllegalAccessException e) {
            logger.error("", e);
        } catch (ClassNotFoundException e) {
            logger.error("", e);
        } catch (SQLException e) {
            logger.error("", e);
        }
        return connection;
    }

    public ResultSet query(Connection conn, String sql) {
        PreparedStatement pStatement = null;
        ResultSet rs = null;
        try {
            pStatement = conn.prepareStatement(sql);
            rs = pStatement.executeQuery();
        } catch (SQLException e) {
            logger.error("", e);
        }
        return rs;
    }

    public boolean queryUpdate(Connection conn, String sql) {
        PreparedStatement pStatement = null;
        int rs = 0;
        try {
            pStatement = conn.prepareStatement(sql);
            rs = pStatement.executeUpdate();
        } catch (SQLException e) {
            logger.error("", e);
        }
        if (rs > 0) {
            return true;
        }
        return false;
    }


}

java代码模拟行锁、表锁发生死锁(运行单元测试即可复现)
package com.hikvision.data.test;

import com.hikvision.data.modules.backup.PgTool;
import org.apache.ibatis.jdbc.ScriptRunner;
import org.junit.Before;

import java.io.Reader;
import java.io.StringReader;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class DeadLockTest {

    //需要事先执行如下SQL
    @Before
    public void init() {
/**
         drop table if exists tb_user;
         create table tb_user
         (
         id    integer not null,
         name varchar(64),
         age int4,
         constraint pk_id primary key (id)
         );
         insert into tb_user(id, name, age) values (1, '张三', 100);
         insert into tb_user(id, name, age) values (2, '李四', 200);
         select * from tb_user;

         update tb_user set name = '张三' where id = 1;
         update tb_user set name = '李四' where id = 2;


         drop table if exists tb_fruit;
         create table tb_fruit
         (
         id    integer not null,
         name varchar(64),
         age int4,
         constraint pk_fruit_id primary key (id)
         );
         insert into tb_fruit(id, name, age) values (1, '天麻', 100);
         insert into tb_fruit(id, name, age) values (2, '火龙果', 200);
         select * from tb_fruit;
 */
    }


    /**
     * 演示行锁发生死锁
     */
    @org.junit.Test
    public void testRowDeadLock() {

        int total = 2;
        CountDownLatch latch = new CountDownLatch(1);
        List<Thread> threads = new ArrayList<>();
        for (int i = 0; i < total; i++) {
            RowDeadLockTask runner = new RowDeadLockTask(latch, i);
            Thread t = new Thread(runner, "dead-" + i);
            threads.add(t);
        }
        for (Thread thread : threads) {
            thread.start();
        }

        System.out.println("停顿10秒");
        try {
            TimeUnit.SECONDS.sleep(10L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        latch.countDown();
        System.out.println("停顿10秒结束,开始运行任务");
        try {
            CountDownLatch wait = new CountDownLatch(1);
            wait.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 演示表锁发生死锁
     */
    @org.junit.Test
    public void testTableDeadLock() {

        int total = 2;
        CountDownLatch latch = new CountDownLatch(1);
        List<Thread> threads = new ArrayList<>();
        for (int i = 0; i < total; i++) {
            TableDeadLockTask runner = new TableDeadLockTask(latch, i);
            Thread t = new Thread(runner, "dead-" + i);
            threads.add(t);
        }
        for (Thread thread : threads) {
            thread.start();
        }

        System.out.println("停顿10秒");
        try {
            TimeUnit.SECONDS.sleep(10L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        latch.countDown();
        System.out.println("停顿10秒结束,开始运行任务");
        try {
            CountDownLatch wait = new CountDownLatch(1);
            wait.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }



    private static StringReader reader1() {
        String a =
                "begin;\n" +
                "select * from tb_user where id = 1 for update;\n" +
                "update tb_user set name = '张三11111' where id = 1;\n" +
                "\n" +
                "select * from tb_user where id = 2 for update;\n" +
                "update tb_user set name = '李四2222222' where id = 2;\n" +
                "commit;";
        StringReader reader = new StringReader(a);
        return reader;
    }

    private static StringReader reader2() {
        String a =
                "begin;\n" +
                "select * from tb_user where id = 2 for update;\n" +
                "update tb_user set name = '李四2222222' where id = 2;\n" +
                "\n" +
                "select * from tb_user where id = 1 for update;\n" +
                "update tb_user set name = '张三11111' where id = 1;\n" +
                "commit;";
        StringReader reader = new StringReader(a);
        return reader;
    }


    private static StringReader reader3() {
        String a =
                "begin;\n" +
                "lock table tb_user in ACCESS exclusive mode;\n" +
                "update tb_user set name = '张三11111' where id = 1;\n" +
                "lock table tb_fruit in ACCESS exclusive mode;\n" +
                "update tb_fruit set name = '红心天麻' where id = 1;\n" +
                "commit;";
        StringReader reader = new StringReader(a);
        return reader;
    }


    private static StringReader reader4() {
        String a =
                "begin;\n" +
                "lock table tb_fruit in ACCESS exclusive mode;\n" +
                "update tb_fruit set name = '红心天麻' where id = 1;\n" +
                "lock table tb_user in ACCESS exclusive mode;\n" +
                "update tb_user set name = '张三11111' where id = 1;\n" +
                "commit;";
        StringReader reader = new StringReader(a);
        return reader;
    }


    public static final class RowDeadLockTask implements  Runnable {

        private CountDownLatch countDownLatch;
        private int index;

        public RowDeadLockTask(CountDownLatch countDownLatch, int index) {
            this.countDownLatch = countDownLatch;
            this.index = index;
        }

        @Override
        public void run() {
            Connection connection = null;
            try {
                connection = new PgTool().getConnection("10.42.43.9", 5432, "postgres", "postgres", "123qaz!@#");
                ScriptRunner scriptRunner = new ScriptRunner(connection); //该类是由,mybatis框架提供的
                scriptRunner.setAutoCommit(true);
                scriptRunner.setSendFullScript(true);
                Reader reader = null;
                int i = index % 2;
                if (i == 1) {
                    reader = reader1();
                } else {
                   reader =  reader2();
                }
                System.out.println("运行sql开始:  " + index);
                countDownLatch.await();
                scriptRunner.runScript(reader);
                System.out.println("运行sql结束:  " + index);
            } catch (Throwable e) {
                e.printStackTrace();
            }finally {
                try {
                    connection.close();
                } catch (Throwable throwables) {
                    throwables.printStackTrace();
                } finally {
                }

            }

        }
    }


    public static final class TableDeadLockTask implements Runnable {

        private CountDownLatch countDownLatch;
        private int index;

        public TableDeadLockTask(CountDownLatch countDownLatch, int index) {
            this.countDownLatch = countDownLatch;
            this.index = index;
        }

        @Override
        public void run() {
            Connection connection = null;
            try {
                connection = new PgTool().getConnection("10.42.43.9", 5432, "postgres", "postgres", "123qaz!@#");
                ScriptRunner scriptRunner = new ScriptRunner(connection); //该类是由,mybatis框架提供的
                scriptRunner.setAutoCommit(true);
                scriptRunner.setSendFullScript(true);
                Reader reader = null;
                int i = index % 2;
                if (i == 1) {
                    reader = reader3();
                } else {
                    reader = reader4();
                }
                System.out.println("运行sql开始:  " + index);
                countDownLatch.await();
                scriptRunner.runScript(reader);
                System.out.println("运行sql结束:  " + index);
            } catch (Throwable e) {
                e.printStackTrace();
            } finally {
                try {
                    connection.close();
                } catch (Throwable throwables) {
                    throwables.printStackTrace();
                } finally {
                }

            }

        }
    }





}


PostgreSql简介 PostgreSQL简介 阅读详情

相关推荐

【PostgreSQL】手把手教学PostgreSQL

PostgreSQL 是一个功能强大的开源对象关系数据库系统,它使用和扩展了 SQL 语言,并结合了许多安全存储和扩展最复杂数据工作负载的功能。PostgreSQL 因其经过验证的架构、可靠性、数据完整性、强大的功能集、可扩展性以及软件背后的开源社区致力于始终如一地提供高性能和创新的解决方案而赢得了良好的声誉。数据类型基元:整数、数字、字符串、布尔值结构化:日期/时间、数组、范围/多范围、UUID文档:JSON/JSONB、XML、KEY-VALUE (HSTORE)几何:点、线、圆、多边形。

Fanjufei的博客 5572

PostgreSQL 基础(一)-- 新手教程

PostgreSQL 基础(一)-- 教程

chinusyan的专栏 1万+

Go sqlx包 + postges pq包实现postgres的批量插入、更新

当有大量数据需要插入时,批量操作省去了大量建立、关闭连接的操作,将多次数据库写IO操作合并成一次操作,省去了很多不必要的时间消耗,将显著提高写效率。

酱油蔡的酱油坛 9995

PGSQL(PostgreSQL)数据库基础篇:PostgreSQL 的 主要优点 、 劣势 、体系结构 、核心功能 、安装教程。

1.最新版本和历史版本不分离存储,导致清理老旧版本时需要做更多的扫描,代价比较大但一般的数据库都有高峰期,如果合理安排VACUUM,这也不是很大的问题,而且在PostgreSQL9.0中VACUUM进一步被加强了。2.在PostgreSQL中,由于索引完全没有版本信息,不能实现Coverage index scan,即查询只扫描索引,不能直接从索引中返回所需的属性,还需要访问表,而Oracle与Innodb则可以。因为存储过程的存在也避免了在网络上大量原始的SQL语句的传输,这样的优势是显而易见的。

一码归一码@ 1万+

ESP32对接百度智能云语音识别:从硬件配置到API调用的完整指南

本文详细介绍了ESP32对接百度智能云语音识别的完整流程,从硬件配置到API调用,涵盖麦克风选择、音频处理、错误处理及性能优化等关键环节。通过实战案例展示如何实现低成本、高效率的语音交互方案,特别适合智能硬件开发者参考。

weixin_29198045的博客 372

机器学习ROC曲线中的阈值thresholds

在ROC曲线上的不同点对应于不同的阈值。根据任务的具体要求,可以选择合适的阈值,以达到平衡召回率和误报率,或者根据具体应用场景调整模型的工作点。,表示样本属于正例的概率。这个概率值可以被截断为二元分类的决策,通过选择一个阈值来决定样本是被分类为正例还是负例。通过改变阈值,可以得到不同的真正例率(TPR)和假正例率(FPR),从而绘制出ROC曲线。总体来说,ROC曲线提供了模型在不同阈值下的性能综合情况,帮助分析模型的分类能力。通常来说,随着阈值的增加,TPR会减小,而FPR会增加。ROC曲线的绘制涉及。

行子的博客 3654

数据库越来越慢,我却一直找不到原因——直到装上Postgres Exporter找到了原因

PostgreSQL性能监控方案:Postgres Exporter部署指南 摘要:本文介绍了如何通过Postgres Exporter实现对PostgreSQL数据库的全面监控。Postgres Exporter作为Prometheus与PostgreSQL之间的桥梁,能够自动采集数百项关键指标(连接数、查询性能、缓存命中率等),帮助运维人员快速定位数据库性能问题。文章详细讲解了CentOS7环境下Postgres Exporter的安装步骤、监控用户权限配置方法,以及如何将Exporter配置为系统服务

liu_chen_yang的博客 1万+

2026零成本私有化:OpenClaw一键搭建Discord/Telegram智能机器人,数据不出本地,永久免费替代ChatGPT

如果内置的功能不能满足你的需求,你可以很容易地添加自己的自定义工具。public string Description => "查询指定城市的天气";// 调用天气API获取天气信息return $"city今天的天气是晴,温度25度";// 注册工具今天北京的天气怎么样?大模型的选择很重要:不要盲目追求大参数的模型。对于大多数场景来说,7B参数的模型已经足够用了,而且速度快,内存占用低。上下文长度不要设置太大:上下文长度越大,内存占用越高,推理速度越慢。

2601_94871597的博客 259

从 WAL 到实时变更流Flink Postgres CDC Connector 实战

PostgreSQL CDC连接器将数据库表转为可实时更新的流表,支持首次快照扫描后持续消费WAL日志变更。使用需配置逻辑复制槽和适当的解码插件(如pgoutput)。核心配置包括基础连接参数、复制槽名称、解码插件类型及快照模式。增量快照功能支持并行读取和chunk粒度检查点,优化大表处理效率。LSN提交延迟策略确保容灾恢复能力。通过Flink SQL可便捷创建CDC源表,适用于构建实时数据处理管道。

hello.reader 2071

逆向淘宝x-mini-wua:从加密算法到设备指纹的生成逻辑

本文深入剖析了淘宝风控核心参数x-mini-wua的生成逻辑与加密算法。通过逆向分析,揭示了其作为设备“身份证”的作用,详细拆解了从硬件信息采集、SG_INNER_DATA文件解密、关键参数提取到最终长wua合成的完整技术链条,并探讨了模拟生成与绕过风控的实战思路及注意事项。

year5的博客 1075

超10万,两台Mac Studio在家就能跑满血DeepSeek,网友:这是性价比最高的大模型一体机

在AI计算领域,没有比这更强的个人电脑了。这要从它的架构说起。对于那些有本地部署满血版DeepSeek需求的用户,目前建议的配置是选购512GB统一内存 + 1TB SSD,搭载M3 Ultra芯片的Mac Studio,官网售价74249元,可以叠加国补、教育优惠、12期分期等,这可能是目前门槛最低、性价比最高的满血版DeepSeek本地部署方案。对于企业而言,尽管Mac Studio确实可以部署6000亿参数的大模型,但在内存带宽、模型精调服务等方面,跟专用的大模型一体机仍有差距,采购需要谨慎评估。

2501_90444774的博客 1914

node-postgres增删改查完全手册:参数化查询与结果集处理,彻底告别SQL注入

**node-postgres(pg)是 Node.js 中功能最完善的 PostgreSQL 客户端**,它通过参数化查询从根本上杜绝 SQL 注入,并提供连接池、事务、流式结果集等生产级能力。本文带你从安装、连接,到增删改查的每一步,完整掌握它的参数化查询与结果集处理。 ## 1. 快速上手:安装 node-postgres 与建立连接 一行命令安装核心包: ```sh npm inst

gitblog_01166的博客 216

rk3568 rockit编译测试

编译rockit不能使用SDK默认编译kernel的交叉编译,需要采用编译buildroot的,而编译buildroot的编译器SDK并没有存放,需要编译过buildroot之后才可以用。命令参数相关解析可查阅代码,这里提醒一下-l参数,这是程序运行计数,默认是100,时间很短,基本上显示画面一闪而过,一度以为是程序哪里出问题了,改用-l 1000,画面显示时间加长。此处跳过系统,单领出来编译。rockit组件包在4.10版本需要手动编译,奈何我的版本怎么都编译不了,后来改用5.10版本才编译通过。

zfenggo的博客 4195

Supabase 怎么在 Postgres 中用 Vault 存储加密密钥并在 SQL 中引用?

如果你的 API Key、服务凭证或连接地址不能以明文写进 SQL 函数、触发器或 Webhook 配置里,Supabase Vault 提供了一条落地路径:它是一个 Postgres 扩展加配套的 Dashboard 界面,用于在数据库中以加密形式存储密钥类数据。密钥在磁盘上以认证加密(基于 `libsodium`)的形式保存,之后通过一个自动创建的 Postgres 视图在查询时解密,因此你可

gitblog_00087的博客 916

流体动力学仿真软件:XFlow_(20).案例研究:声学仿真

在流体动力学仿真软件中,声学仿真是一个重要的应用领域。通过数值模拟,工程师和科研人员可以预测和分析流体系统中的声学现象,如气动噪声、声波传播和声场分布。这些仿真结果对于优化设计、降低噪声水平和提高系统性能具有重要意义。本节将详细介绍如何在流体动力学仿真软件中进行声学仿真,包括声学模型的选择、参数设置、后处理分析等内容,并通过具体的案例来说明这些步骤。

kkchenjj的博客 902

借助Gemini 3 Pro高效解决课题申报中的五大核心痛点,亲测有效经验分享

之前给大家分享过关于AI辅助课题申报的相关的内容,涵盖了申报书部分撰写技巧,但没针对性拆解各位同仁在实际申报时遇到的卡壳的地方。比如选题范围拿捏不准,定的太大,根本没法落地完成;定的太小,研究价值则体现不了;写综述时,容易单纯罗列文献,缺乏批判性视角,没办法自然融入自己的判断,找不到研究缺口;研究方法部分,可能担心方法设计不够严谨,别人难以复现.....针对这些申报中的高频痛点,接下来七哥会从五个核心要点出发,借助Gemini 3 Pro高效解决这些痛点。

智能AI让学术科研更容易 700

postgres 多表查询更新

更新一张表a的内容关联其他表作为条件: [code="sql"] update a set name='xx' from t1 t1,t2 t2 where t1.age=t2.age t1.name = a.name [/code] 第二种比较小白我以前的做法 [code="sql"] update tc set task_code = 'xxxx' WHERE ...

liubl2011的专栏 961

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

数据库操作系列-Mysql, Postgres常用sql语句总结

举个栗子: 我想查询users表created_at字段从2023-08-01 00:00:00.000 到2023-08-10 00:00:00.000范围内的数据。在MySQL数据库中,如果在insert语句后面带上ON DUPLICATE KEY UPDATE 子句,而要插入的行与。表中现有记录的惟一索引或主键中产生重复值,那么就会发生旧行的更新;下面的语句有一样的效果,区别在于使用的是 name 字段,而不是约束的名字。使用相同变量,多次执行这段逻辑,我们会发现只创建了一条,所以是成功的~~~

tangdou369098655的博客 1193

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

探索高效SQL构建:honeysql-postgres 项目推荐

探索高效SQL构建:honeysql-postgres 项目推荐 项目介绍 在现代软件开发中,高效地构建和执行SQL查询是每个开发者不可或缺的技能。honeysql-postgres 是一个专为PostgreSQL数据库设计的扩展库,它基于广受欢迎的 honeysql 库,提供了更多针对PostgreSQL的特定SQL语句和功能支持。这个项目的目标是扩展 honeysql 的功能,使其能够支持更多...

gitblog_00250的博客 865

Supabase Iceberg Wrapper:用 SQL 直接在 Postgres 中查询 Apache Iceberg 数据

本文围绕 Supabase Studio 中的 Iceberg Wrapper 集成文档 [overview.md](https://link.gitcode.com/i/370e654a4365786e2ec80bd78aadc505) 展开,讲清楚三件事:Iceberg 表格式为什么适合大规模分析场景、Iceberg Wrapper 作为 Postgres 外部数据包装器(FDW)如何把 Ic

gitblog_01004的博客 662

【GitHub有趣项目】用 SQL 写的俄罗斯方块游戏:Tetris-SQL

wasd是方向键,空格键是下放。p是暂停,q是退出。有时候可能网不好会失败,多执行几次。可能是python没装好,重新装一下。

weixin_48758194的博客 1926

postgres数据库常用函数及语句

本文内容主要包含一些我日常开发中积累下来疑难postgres数据库函数及语句,不包含基础的函数以及创建表结构、修改表结构等ddl语句。

qq_41206236的博客 646

从SQLite到Postgres:Instatic数据库无缝迁移指南

Instatic作为一款现代化的自托管视觉CMS,支持SQLite和Postgres两种数据库引擎。随着项目规模增长,将数据库从SQLite迁移到Postgres能显著提升性能和可靠性。本文将详细介绍迁移的完整流程,帮助你实现数据的无缝过渡。 ## 为什么选择Postgres?迁移前的准备工作 SQLite适合小型部署和开发环境,而Postgres则为生产环境提供更强大的支持: - 支持多用户

gitblog_00989的博客 1080

Webiny Headless CMS 的 Postgres 存储研究:从纯 Postgres 到 Postgres + OpenSearch 双引擎架构的设计决策

Webiny 是一个开源、可自托管的 AWS 无服务端(Lambda / DynamoDB / S3)CMS 平台。本文以 Webiny 仓库中 [Postgres 存储研究系列文档](https://link.gitcode.com/i/6898643ebf16ab220da82eb89e770e3a) 为主线,完整还原该团队为 Headless CMS 引入 Postgres 存储所做的前期调

gitblog_00922的博客 426

【SQL】按某个关联列用一张表的数据更新另一张表

SQL更新表——用一张表的部分字段数据更新另一张表

欢迎指错||纠正||建议||水评+点赞&&评论&&关注&&转发 4901

SkyWalking 监控 PostgreSQL:基于 postgres-exporter 与 OpenTelemetry 的指标采集及慢 SQL 采集方案

本文围绕 SkyWalking OAP 的 PostgreSQL 监控能力展开,系统讲解两条核心链路:一是借助 postgres-exporter 与 OpenTelemetry Collector 将 PostgreSQL 运行指标送入 [Meter 系统](https://link.gitcode.com/i/977d3ee80cb63433d3888a071bd1651f),形成 `Laye

gitblog_01164的博客 384
上一篇: Cas原理备忘-
下一篇: 正则表达式之分组+正/反向肯定/否定预查
lhever_
博客等级 码龄14年 213粉丝 130原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值