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

PostgreSQL最常用数据类型-重点说明自增主键处理

简介

PostgreSQL提供了非常丰富的数据类型,我们平常使用最多的基本就3类:

  1. 数字类型
  2. 字符类型
  3. 时间类型

这篇文章重点介绍这3中类型,因为对于高并发项目还是推荐:尽量使用简单类型,把运算和逻辑放在应用中,而不是数据库上。

如果有离线数据分析处理、做报表等低并发的业务应用,可以多了解一点PostgreSQL的其他类型,作为知识面的拓展,可以在主导设计表的时候有更丰富和灵活的选择,其他类型的详细信息可以参考官方文档。

数字类型

数字类型概览

类型字节长度说明范围
smallint2 字节2字节整数,int2-32768 到 +32767
integer4 字节4字节整数,int,int4-2147483648 到 +2147483647
bigint8 字节8字节大整数,int8-9223372036854775808 到 +9223372036854775807
numeric可变长用户指定的精度,精确小数点前 131072 位;小数点后 16383 位
decimal可变长等价于numeric
real4 字节单精度浮点数,float46 位十进制数字精度
double precision8 字节双精度浮点数,float815 位十进制数字精度
smallserial2 字节自增的小范围整数1 到 32767
serial4 字节自增整数1 到 2147483647
bigserial8 字节自增的大范围整数1 到 9223372036854775807

PostgreSQL没有像MySQL的tinynit这样的1字节整型,如果需要就用smaillint吧,不要用bytea,bytea需要额外的空间,并且要转。

numeric decimal money

postgresql的numeric和decimal等价:numeric可以兼容oracle,decimal可以兼容MySQL。

numeric(precision, scale),numeric(12,4)表示可以存储12位数字,其中小数4位,整数8位(12-4=8)。

存储数据时,整数不能超过8(precision-scale)位,超过8位报错,小数超过4(scale)位会四舍五入。

-- money只保留2位小数
CREATE TABLE price (id SERIAL PRIMARY KEY,var_val VARCHAR(100),price money
);insert into price(var_val,price) values('123456789.123456789',123456789.123456789);
select * from price;

PostgreSQL money类型

CREATE TABLE orders (id SERIAL PRIMARY KEY,var_val VARCHAR(100),numeric_val NUMERIC(12, 4),decimal_val decimal(12, 4)
);
-- 整数超过8位出错-- ERROR:  A field with precision 12, scale 4 must round to an absolute value less than 10^8.numeric field overflow -- ERROR:  numeric field overflow
-- SQL state: 22003
-- Detail: A field with precision 12, scale 4 must round to an absolute value less than 10^8.
insert into orders(var_val,numeric_val,decimal_val) values('123456789.123456789',123456789.123456789,123456789.123456789);

PostgreSQL numeric整数部分不能超

小数位的处理方式,采用四舍五入截断:

-- 运行插入,实际存储值12345678.1235
insert into orders(var_val,numeric_val,decimal_val) values('12345678.123456789',12345678.123456789,12345678.123456789);

PostgreSQL numeric小数部分自动截断

sequence

聊数据库有一个绕不开的话题,自增主键。

对于PostgreSQL聊自增主键之前,我们得先了解一下sequence。

创建sequence与参数

参数说明
INCREMENT步长,每次增加多少
START初始值
MINVALUE最小值
MAXVALUE最大值
CACHE缓存多少,就是一次生成多个缓存起来,默认值1
NO CYCLE表示不循环

创建sequence,名字通常是:表名_字段名_seq

CREATE SEQUENCE IF NOT EXISTS public.user_id_seqINCREMENT 1START 1MINVALUE 1MAXVALUE 2147483647CACHE 1NO CYCLE;

PostgreSQL sequence

调用sequence

使用nextval来触发sequence,让它自增。

-- 让xxx_zzz_seq这个sequence自增
select nextval('xxx_zzz_seq');-- 调用之后,current value自动递增
select nextval('user_id_seq') as r;

表字段关联sequence

alter table table_name alter column id set DEFAULT nextval('xxx_zzz_seq')

可以看到,本质上是表字段设置一个默认值,这个默认值是一个函数nextval,它的参数是sequence的名称。

sequence的其他操作

--删除序列
drop sequence xxx_zzz_seq;--重置序列
alter sequence xxx_zzz_seq restart with 1;--修改序列(修改序列的最小值和最大值)
alter sequence sequence_name MINVALUE new_min_value MAXVALUE new_max_value;

查看sequence信息

sequence的信息可以在pg_sequences表查看。

select * from pg_sequences;

自增主键

MySQL习惯了为表添加自增主键,PostgreSQL想要同样的效果可以使用serial。

其实MySQL和PostgreSQL自增主键的实现完全不一样。

PostgreSQL的serial更像一个语法糖,实际上是通过sequence实现。

serial语法糖

serial不是SQL标准的语法,所以PostgreSQL推荐还是使用标准语法来实现:

-- 创建序列
CREATE SEQUENCE IF NOT EXISTS user_id_seqINCREMENT 1START 1MINVALUE 1MAXVALUE 2147483647CACHE 1OWNED BY "user".id;-- 创建表格,并为id给定默认值,nextval相当于一个函数
CREATE TABLE user (id INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('user_id_seq'),name VARCHAR(100)
);-- 为序列赋予所有权,这个可以省略,因为创建sequence的时候已经指定了
ALTER SEQUENCE user_id_seq OWNED BY user.id;

注意:sequence只是自增,主键还是要使用PRIMARY KEY关键字。

语法糖不标准,但是简洁啊

手动创建sequence看起来就非常麻烦,所以serial该用还得用,反正最后还是转换了。

不信,可以看:

CREATE TABLE seq_serial (id serial NOT NULL PRIMARY KEY,name VARCHAR(100),age smallint
);

转换之后:

CREATE TABLE IF NOT EXISTS public.seq_serial
(id integer NOT NULL DEFAULT nextval('seq_serial_id_seq'::regclass),name character varying(100) COLLATE pg_catalog."default",age smallint,CONSTRAINT seq_serial_pkey PRIMARY KEY (id)
)

PostgreSQ identity default

serial的问题

serial做自增主键有一个问题,就是如果显式的指定了某个自增值之后,肯定会冲突。

插入2个,没有显式指定值,没有问题:

INSERT INTO seq_serial(name, age) VALUES ('allen', 22);
INSERT INTO seq_serial(name, age) VALUES ('bob', 99);

显式指定id值为3,然后再不指定id就会冲突:

INSERT INTO seq_serial(id,name, age) VALUES (3,'alice', 30);-- ERROR:  Key (id)=(3) already exists.duplicate key value violates unique constraint "seq_serial_pkey" 
-- ERROR:  duplicate key value violates unique constraint "seq_serial_pkey"
-- SQL state: 23505
-- Detail: Key (id)=(3) already exists.
INSERT INTO seq_serial(name, age) VALUES ('albert', 25);

因为指定id值的时候,关联的sequence并没有更新。

所以使用serial的时候,一定不要在显式的指定自增主键的值了。

和serial有相同问题的还有:GENERATED BY DEFAULT AS IDENTITY,本质也是sequence。

CREATE TABLE user_default (id bigint PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,name varchar(30),age smallint
);

转换之后:

CREATE TABLE IF NOT EXISTS public.user_default
(id bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1 ),name character varying(30) COLLATE pg_catalog."default",age smallint,CONSTRAINT user_default_pkey PRIMARY KEY (id)
)

这个没有看到nextval,其实还是sequence,只是变成隐式的了:

PostgreSQ sequence隐式转换

更优雅的自增主键

我们前面说了serial的问题,有显式指定值,从而主键冲突的情况,如何避免呢?

可以使用:GENERATED ALWAYS AS IDENTITY

CREATE TABLE user_always (id bigint PRIMARY KEY GENERATED ALWAYS AS IDENTITY,name varchar(30),age smallint
);
INSERT INTO user_always(name, age) VALUES ('allen', 22);
INSERT INTO user_always(name, age) VALUES ('bob', 99);

不能显式指定值:

-- ERROR:  Column "id" is an identity column defined as GENERATED ALWAYS.cannot insert a non-DEFAULT value into column "id" -- ERROR:  cannot insert a non-DEFAULT value into column "id"
-- SQL state: 428C9
-- Detail: Column "id" is an identity column defined as GENERATED ALWAYS.
-- Hint: Use OVERRIDING SYSTEM VALUE to override.
INSERT INTO user_always(id,name, age) VALUES (3,'alice', 30);

我们可以看到如果显式指定值,就会提示我们,不能插入非默认值。

PostgreSQL identity只能默认主键

如果一定要显式指定,怎么操作,使用DEFAULT参数自动生成,不能使用自定义值。

INSERT INTO userb(id,name, age) VALUES (DEFAULT,'alice', 30);

无符号整型

postgresql没有无符号类型,可以通过check检查,虽然不能再数据范围上改变,但是,可以约束字段。

CREATE TABLE products (id int not null primary key generated always as identity,name varchar(50),price numeric CHECK (price > 0)
);
-- ERROR:  Failing row contains (1, 羽绒服, -1).new row for relation "products" violates check constraint "products_price_check" -- ERROR:  new row for relation "products" violates check constraint "products_price_check"
-- SQL state: 23514
-- Detail: Failing row contains (1, 羽绒服, -1).
insert into products(name,price) values('羽绒服',-1);

PostgreSQL check检查

字符类型

字符类型基本说明

类型说明
char(n)固定长度,最多10485760字节(1GB),默认长度1
bpchar(n)等价于char(n)
varchar(n)可变长度长度,最多10485760字节(1GB)
character(n)等价于char(n)
character varying(n)等价于varchar(n)
text无长度限制

推荐使用char、varchar,这个是SQL的标准类型,看起来也更简洁一些。

char是固定长度,使用空格填充,所以也叫bpchar(blank pad char)

对于一些固定长度的字段非常合适,例如md5、手机号码等。

-- true char比较的时候只会比较值,统计长度时、转换为其他类型时候也会删除填充的空格
select 'aa'::char(20)='aa'::char(10) as r1,
length('aa'::char(10)) as r2,
,length('aa'::char(10)::varchar(3)) as r3;

PostgreSQL char数据类型

字符编码与排序

通常我们是不会关系编码和排序相关信息,因为使用默认的设置就可以。

但是,我们最好了解一下,避免碰到问题两眼一抹黑。

在PostgreSQL中有3个概念比较重要:

  1. encoding:这个好理解,就是字符编码
  2. collate:字符串排序规则
  3. ctype:字符分类,定义什么是字符,大小写是否相等

PostgreSQL中可以在创建表的时候和做比较操作的时候指定collate:

CREATE TABLE user_collate (a text COLLATE "my_collation",b text COLLATE "my_collation"
);
SELECT a < ('what 王德发' COLLATE "my_collation") FROM user;

注意:和MySQL不同,上面collate不是单独collate,而是指collation的name,collation是包含collate和ctype。

可以通过下面语句创建。

CREATE COLLATION collation_name (LC_COLLATE = 'zh_CN.UTF-8',LC_CTYPE = 'zh_CN.UTF-8'
);

创建完成,可以通过下面的语句查看:

SELECT * from pg_collation;

如果我们没有指定,默认使用的是default,就是创建数据库上指定的值,如:

CREATE DATABASE db_name WITH ENCODING 'UTF8' LC_COLLATE='C' LC_CTYPE='C' TEMPLATE=template0;-- 修改
update pg_database set datcollate='en_US.utf8',datctype='en_US.utf8' where datname='db_name';
CREATE TABLE IF NOT EXISTS basic_file_info
(fid bigint NOT NULL,report_type numeric(3,0),business_type character varying(255) COLLATE pg_catalog."default",area character varying(50) COLLATE pg_catalog."default",file_name character varying(300) COLLATE pg_catalog."default",CONSTRAINT basic_file_info_pkey PRIMARY KEY (fid)
)

可以通过下面语句来查看:

SELECT * from pg_database;

MySQL的collate就包含了排序和是否忽略大小写相关的内容:

CREATE TABLE user (id int NOT NULL,name varchar(30) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8_general_ci COMMENT='user';

测试不同collation对字段排序的影响:

CREATE COLLATION zhutf8 (LC_COLLATE = 'zh_CN.UTF-8',LC_CTYPE = 'zh_CN.UTF-8'
);CREATE COLLATION enuft8 (LC_COLLATE = 'en_US.UTF-8',LC_CTYPE = 'en_US.UTF-8'
);CREATE TABLE user_collate (id serial not null primary key,a text COLLATE "zhutf8",b text COLLATE "enuft8"
);insert into user_collate(a,b) values
('a','a'),
('A','A'),
('b','b'),
('B','B'),
('bca','bca'),
('一二三','一二三'),
('一二三b','一二三b'),
('王德发','王德发');
select * from user_collate order by a;
select * from user_collate order by b;

PostgreSQL collate对排序影响

我们可以通过COLLATION来创建一些特殊的比较规则,如:

  1. 让大写字母排前面(通常默认是使用ascii码排序,小写字母会排前面)
  2. 忽略大小写
  3. 忽略数字和标点符号
-- 忽略口音和大小写
CREATE COLLATION ignore_accent_case (provider = icu, deterministic = false, locale = 'und-u-ks-level1');
SELECT 'Å' = 'A' COLLATE ignore_accent_case; -- true
SELECT 'z' = 'Z' COLLATE ignore_accent_case; -- true-- 大写字母排前面
CREATE COLLATION upper_first (provider = icu, locale = 'und-u-kf-upper');
SELECT 'B' < 'b' COLLATE upper_first; -- true-- 数字当数字比较、忽略标点符号
CREATE COLLATION num_ignore_punct (provider = icu, deterministic = false, locale = 'und-u-ka-shifted-kn');
SELECT 'id-45' < 'id-123' COLLATE num_ignore_punct; -- true
SELECT 'w;x*y-z' = 'wxyz' COLLATE num_ignore_punct; -- true
SELECT 'id-45' < 'id-123' COLLATE num_ignore_punct as r1,
'id-45' < 'id-123' as r2,
'45' < '123' COLLATE num_ignore_punct as r3,
'45' < '123' as r4;

PostgreSQL 定制排序规则

前面几个例子,可以参考官方文档:ICU-CUSTOM-COLLATIONS

关于字符集、比较和本地化的更多内容,也可以参考:

collation

字符集支持

本地化-locale涉及日期、时间、数字、货币等

时间日期时间戳

基本类型说明

PostgreSQL有非常丰富的时间相关类型。

类型说明
timestamp(n) without time zone不带时区的时间戳,8字节
timestamp(n) with time zone带时区的时间戳,8字节
date日期,4字节
time(n) without time zone不带时区的时间,8字节
time(n) with time zone带时区的时间,12字节
interval时间间隔,16字节

上面除了date的精度是1天,其他类型的最大精度都是微秒(1/1000000秒)

interval

interval支持ISO8601格式,P后面表示日期,T后面表示日期。

interval类型可以使用Java的Duration来存储。

select '2 years 15 months 100 weeks 99 hours 123456789 milliseconds'::interval as r1,
'P1Y2M3DT4H5M6S'::interval as r2;

interval最常用来做计算而不是存储,例如:

select now(),now() - interval '1 day' as subday,
now() + interval '1 week' as addweek,now() - interval '1 month' as submonth,now()+interval '1 year' as addyear;--加1年1月1天1时1分1秒
select now() + interval '1 year 1 month 1 day 1 hour 1 min 1 sec';

关于时间的计算和函数,可以参数:PostgreSQL常用时间函数与时间计算提取示例说明

时区

查看设置时区:

show timezone;SET TIMEZONE ='Australia/Sydney';

时区转换:

SELECT localtimestamp as lt,current_timestamp as ct,
timezone('Australia/Sydney',current_timestamp) as sydney_time,
timezone('America/New_York',current_timestamp) as newyork_time;

timestamptz

timestamp(n) with time zone可以简写为timestamptz,这个类型可以通过下面的语句查询:

SELECT typname, typlen FROM pg_type WHERE typname like 'timestamp%';
CREATE TABLE ts_tz_n (id serial not null primary key,ts TIMESTAMPTZ default current_timestamp, ts0 TIMESTAMPTZ(0) default current_timestamp,ts1 TIMESTAMPTZ(1) default current_timestamp,ts2 TIMESTAMPTZ(2) default current_timestamp,ts3 TIMESTAMPTZ(3) default current_timestamp,ts4 TIMESTAMPTZ(4) default current_timestamp,ts5 TIMESTAMPTZ(5) default current_timestamp,ts6 TIMESTAMPTZ(6) default current_timestamp,ts7 TIMESTAMPTZ(7) default current_timestamp
);

PostgreSQL 时间戳精度

timestamptz最大精度是6位,到微秒,所以超过6位会提示如下的警告,并自动修正为6位。

WARNING: TIMESTAMP(7) WITH TIME ZONE precision reduced to maximum allowed, 6

如果没有指定精度,那么默认也是6位精度,到微秒。

timestamptz可以使用Java的OffsetDateTime来存储。

timestamp

timestamp和timestamptz的区别在于:timestamp不带时区,可以看做是MySQL的datetime类型。

CREATE TABLE ts_n (id serial not null primary key,ts TIMESTAMP default current_timestamp, ts0 TIMESTAMP(0) default current_timestamp,ts1 TIMESTAMP(1) default current_timestamp,ts2 TIMESTAMP(2) default current_timestamp,ts3 TIMESTAMP(3) default current_timestamp,ts4 TIMESTAMP(4) default current_timestamp,ts5 TIMESTAMP(5) default current_timestamp,ts6 TIMESTAMP(6) default current_timestamp,ts7 TIMESTAMP(7) default current_timestamp
);

timestamp可以使用Java的Timestamp来存储。

timestamp和timestamptz怎么选?

没有国际化的需求无脑选timestamp就对了。

有国际化的也可以用timestamp,把转换操作放在应用层就可以。

时间戳的疑问

有朋友可能会有疑问,我平时看到的时间戳就是1732523307、或者1732523307672这样的一个数字,他为什么会有时区呢?

我们先来看一下时间戳的定义:

时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总秒数

所以,我们经常看到的类似于1732523307这样的10位数字,的确是时间戳,这个是unix的时间戳。

实际在数据库和编程语言中,还有一个epoch概念,toEpochSecond就是10位秒时间戳,toEpochMilli就是13位毫秒时间戳。

在PostgreSQL中我们可以通过extract来获取:

-- 1732523307.672621
SELECT extract(epoch from now()) as r1;

我们可以看到PostgreSQL非常严谨,时间戳定义为秒,它的精度是微秒,它就用小数来表示。

根据时间戳的定义,我们知道不同时区同一时间的时间戳相同,我再此刻生成一个时间戳,不管是在北京生成的,还是在纽约生成的,都是相同的数字。

那为什么timestamptz还有时区,这不是很奇怪么?

timestamptz只是表示时间戳,它有自己的结构,转换为epoch还是等于10位的整数时间戳。

带时区,主要是为了转换显示为本地时间,因为我们数据库查看的时候,通常不会查看一个整数,而是本地化之后的时间。

这样如果有国际化的需求,就能一眼看出其中的时间差别。

timestamp与整型时间戳互转

最高精度到微秒:

select extract(epoch from now()) as r,
floor(extract(epoch from now())) as r1,
floor(extract(epoch from now())*1000) as r2,
extract(epoch from now())*1000000 as r3;

PostgreSQL 时间戳转unix时间戳

to_timestamp接收的参数是10位秒,获取到的是一个带时区的时间戳timestamptz:

select to_timestamp(1732610870057034 / 1000000) as r1,
to_timestamp(1732610870057 / 1000) as r2,
to_timestamp(1732610870) as r3;

unix时间戳转PostgreSQL时间戳

有朋友肯定在想,精确到微秒,那用微秒级时间戳来做自增主键,那不得能支持10w并发(秒后6位10万级)。

理论上是这样,但实际上可能有点差距,可以看一下下面的SQL:

do $$
declarei int;
beginfor i in 1..100000000 loopif i % 10000000 = 0 thenraise notice '%',extract(epoch from current_timestamp);end if;end loop;
end;
$$

执行时间肯定超过微秒,但输出时间并没有变化:

PostgreSQL内部调用时间可能有缓存
不太熟悉上面存储过程的朋友可以看一下:PostgreSQL存储过程

bit

类型说明
bit(n)固定长度,默认长度1
varbit(n)可变长度位
bit varying(n)可变长度位,等价于varbit(n)

注意:bit的n是精确值,就是设置n为3,那么必须插入3位值,不能少也不能多,不像char少了会用空格填充。

CREATE TABLE table_bit(col_bit bit(3), col_varbit varbit(5));-- B表示这是一个二进制串
INSERT INTO table_bit VALUES (B'101', B'00');-- ERROR:  bit string length 2 does not match type bit(3) 
-- SQL state: 22026
INSERT INTO table_bit VALUES (B'10', B'101');-- 可以强转为3位,在尾部填充0
INSERT INTO table_bit VALUES (B'10'::bit(3), B'101');

bit是2进制位,一个比较典型的应用场景是开关。

比如,我有一条数据的校验可能有20个校验类型,每个校验类型都有1个开关,怎么设计呢?

当然,可以设置20个字段来分别表示,但是,不够优雅。

我们可以用一个bit(20)的字段来表示,1表示开启,0表示关闭,这样可以通过位运算,可以非常方便知道哪些校验开启了,哪些校验关闭了。

CREATE TABLE check_bit(id serial not null primary key,switch bit(20));INSERT INTO check_bit(switch) VALUES (B'00000000000000000101');
INSERT INTO check_bit(switch) VALUES (B'00000000000000000001');
INSERT INTO check_bit(switch) VALUES (B'00000000000000000100');

这种设计也可以查询开启指定校验的数据有哪些。

通过位运算的方式:

例如,最后1位表示数据正确性校验,现在想要知道哪些数据开启了数据正确性校验,就可以通过下面的方式查询:

select * from check_bit where (switch & B'00000000000000000001') = B'00000000000000000001';

PostgreSQL 位运算

这种查询方式,会在数据库上做大量的运算,所以,这种查询最好确保有其他的条件能先过滤掉大部分数据。

bytea(二进制数据)

输入输出

一提到二进制数据,很多朋友就想到文件、图片之类的资源。

很多设计也这么做,例如工作流引擎Camunda,就把流程图资源保存到数据库。

通常不建议把文件之类的资源放在数据库中,Camunda这样设计是因为它是框架,为了管理避免数据丢失了。

bytea按字节存储,PostgreSQL接受2中输入方式:

  1. hex:16进制
  2. escape:转义字符

输出方式也支持上面2种方式,可以配置:

-- 输出为16进制
SET bytea_output = 'hex'-- 输出为转义字符
SET bytea_output = 'escape';

escape转义是\八进制(进制对应关系可以参考后面的ASCII表):

PostgreSQL bytea输出模式

Java对应类型处理

create table bytea_table(id serial not null primary key,bin_data bytea
);

插入:

@Test
void insert() throws SQLException {String url = "jdbc:postgresql://127.0.0.1:5432/postgres";try (Connection connection = DriverManager.getConnection(url, "root", "")) {assert connection != null;String sql = "INSERT INTO bytea_table(bin_data) VALUES (?)";PreparedStatement ps = connection.prepareStatement(sql);byte[] data = "hello world".getBytes(StandardCharsets.UTF_8);ps.setBytes(1, data);ps.executeUpdate();ps.close();}
}

查看:

@Test
void query() throws SQLException {String url = "jdbc:postgresql://127.0.0.1:5432/postgres";try (Connection connection = DriverManager.getConnection(url, "root", "")) {assert connection != null;String sql = "select bin_data from bytea_table";PreparedStatement ps = connection.prepareStatement(sql);ResultSet rs = ps.executeQuery();while (rs.next()){System.out.println(new String(rs.getBytes(1)));}}
}

PostgreSQL bytea输出示例

网络地址

PostgreSQL提供了处理ip和mac地址的类型,可以非常方便计算。

可能我们很少用这些ip来参与计算,但是可以作为小工具来用,还是非常方便。

例如,计算子网掩码、网络地址等。

类型说明
cidr7字节(ipv4)、19字节(ipv6)
inet7字节(ipv4)、19字节(ipv6)
macaddr6字节,MAC地址
macaddr88字节,MAC地址
CREATE TABLE ip_table (id serial not null PRIMARY KEY,ip_net inet,ip_cidr cidr
);INSERT INTO ip_table (ip_net,ip_cidr) VALUES ('192.168.0.1','192.168.0.1');
INSERT INTO ip_table (ip_net,ip_cidr) VALUES ('192.168.0.0/24','192.168.0.0/24');
INSERT INTO ip_table (ip_cidr) VALUES ('128.1.2');
INSERT INTO ip_table (ip_cidr) VALUES ('128.1');
INSERT INTO ip_table (ip_cidr) VALUES ('128');
-- inet类型必须是完整的ip或者网络
-- INSERT INTO ip_table (ip_net) VALUES ('128');SELECT * FROM ip_table;
select broadcast('192.168.1.5/24') as 广播地址,
host('192.168.1.5/24') as 主机地址,
hostmask('192.168.23.20/30') as 主机掩码,
masklen('192.168.1.5/24') as 掩码长度,
netmask('192.168.1.5/24') as 子网掩码,
network('192.168.1.5/24') as 网络地址,
family(inet '::1') ip4或ip6,
inet_same_family(inet '192.168.1.5/24', inet '::1') as 是否是相同网络族,
inet_merge('192.168.1.5/24', '192.168.2.5/24') as 包含两个给定网络的最小网络;

PostgreSQL 网络地址函数

-- 192.168.1.7这个ip是否属于192.168.1/24这个网络
select inet '192.168.1.7' << inet '192.168.1/24' as r;-- 192.168.1/24网络是否包含或者等于192.168.1/25网络
select inet '192.168.1/25' <<= inet '192.168.1/24' as r;
select ~ inet '192.168.1.6' as op_异或,
inet '192.168.1.6' & inet '0.0.0.255' as op_与,
inet '192.168.1.6' | inet '0.0.0.255' as op_或;

很多时候我们查看的时候只知道ip和网络掩码,并不知道网络长度,怎么计算网络地址呢?

network函数显然不行了,我们可以自己手动计算(ip & 子网掩码):

select network('10.185.33.8') as r, 
inet '255.255.252.0' & inet '10.185.33.8' as r2;

更多可以参考官方文档:网络地址与函数

枚举

枚举有用吗?

当然有用,例如一个订单状态,可能好多地方都会使用,我们如果用枚举约束,就比较出现未知类型。

但是,枚举最大的问题在于,它是我们自定义的类型,很多框架是不支持,都需要我们自己单独处理。

所以,需要考虑迁移维护和兼容问题。

基本操作(创建、修改、添加)

-- 创建枚举
CREATE TYPE cup_enum as ENUM ('中杯', '大杯', '特大杯', '超大杯');-- 重命名枚举
ALTER TYPE cup_enum RENAME TO cup_enum_all;-- 添加枚举值
ALTER TYPE cup_enum ADD VALUE '超超大杯';-- 指定添加位置
ALTER TYPE cup_enum ADD VALUE '超超大杯' BEFORE '超大杯';
ALTER TYPE cup_enum ADD VALUE '超超大杯' AFTER '超大杯';-- 删除枚举
DROP TYPE cup_enum;

查看枚举(第1个、最后1个、枚举范围)

-- 查看第1个最后1个
select enum_first(null::cup_enum),
enum_first('超大杯'::cup_enum),
enum_last(null::cup_enum),
enum_last('大杯'::cup_enum);-- 查看枚举值
SELECT enum_range(null::cup_enum) as r1,
enum_range(null::cup_enum) as r2,
enum_range('大杯'::cup_enum,'超大杯'::cup_enum) as r3;SELECT UNNEST(enum_range(null::cup_enum)) as r1;

PostgreSQL 查看枚举

插入

CREATE TABLE enum_table (id serial not null primary key,cup cup_enum
);
INSERT INTO enum_table(cup) VALUES ('大杯');
INSERT INTO enum_table(cup) VALUES ('特大杯');
INSERT INTO enum_table(cup) VALUES ('超大杯');

不能插入枚举中不存在的值:

-- ERROR:  invalid input value for enum cup_enum: "无敌大杯"
-- LINE 1: INSERT INTO enum_table(cup) VALUES ('无敌大杯');
-- SQL state: 22P02
-- Character: 37
INSERT INTO enum_table(cup) VALUES ('无敌大杯');

查询

select min(cup),max(cup) from enum_table;SELECT * FROM enum_table WHERE cup = '特大杯';

PostgreSQL 枚举查询

查看枚举信息

select * from pg_enum;-- Psql中可以使用
\dT+ enum_name

枚举Java类型处理

在pgAdmin、psql中我们插入枚举值用字符串没有问题。

但是在jdbc中我们插入枚举值,直接用string有问题。

@Test
void insert() throws SQLException {String url = "jdbc:postgresql://127.0.0.1:5432/postgres";Connection connection = DriverManager.getConnection(url,"postgres","");assert connection != null;String sql = "INSERT INTO enum_table(cup) VALUES (?)";PreparedStatement ps = connection.prepareStatement(sql);ps.setString(1,"特大杯");ps.executeUpdate();ps.close();connection.close();
}

大概会报下面的这个错误:

org.postgresql.util.PSQLException: ERROR: column "cup" is of type cup_enum but expression is of type character varying建议:You will need to rewrite or cast the expression.位置:37

我们需要使用setObject,类型使用java.sql.Types.OTHER

@Test
void insert() throws SQLException {String url = "jdbc:postgresql://127.0.0.1:5432/postgres";Connection connection = DriverManager.getConnection(url,"postgres","");assert connection != null;String sql = "INSERT INTO enum_table(cup) VALUES (?)";PreparedStatement ps = connection.prepareStatement(sql);ps.setObject(1,"特大杯", Types.OTHER);ps.executeUpdate();ps.close();connection.close();
}

PostgreSQL的一些表

表名说明
pg_tables可以查看数据库中的表
pg_type可以查看PostgreSQL的数据类型
pg_database可以查看PostgreSQL的所有数据库
pg_namespace可以查看PostgreSQL的所有命名空间,命名空间是对表、索引函数等的抽象
pg_tablespace可以查看PostgreSQL的所有表空间,表空间是对磁盘数据的抽象,一个表空间可以有多个磁盘位置,\db
information_schema.tables类似于MySQL的information_schema.tables
information_schema.columns类似于MySQL的information_schema.columns
pg_enum枚举信息表
select * from pg_type;select * from pg_tables;

表空间再多说2句:

PostgreSQL默认有2个表空间:

  1. pg_default:创建数据库默认表空间,对应的目录PGDATA/base
  2. pg_global:共享系统表如pg_database、pg_tables等,对应的目录PGDATA/global
SELECT d.oid,d.datname,t.oid,t.spcname from pg_database d join pg_tablespace t on d.dattablespace=t.oid;

通常我们使用默认表空间就可以了,如果有需要可以下吗方式创建

-- 创建表空间
CREATE TABLESPACE appdatas LOCATION 'F:\PostgreSQL17\data\appdatas';
-- 给用户赋权
GRANT CREATE ON TABLESPACE appdatas TO user_name;

附录-ASCII

Bin (二进制)Oct (八进制)Dec (十进制)Hex (十六进制)缩写/字符解释
0000 00000000x00NUL(null)空字符
0000 00010110x01SOH(start of headline)标题开始
0000 00100220x02STX (start of text)正文开始
0000 00110330x03ETX (end of text)正文结束
0000 01000440x04EOT (end of transmission)传输结束
0000 01010550x05ENQ (enquiry)请求
0000 01100660x06ACK (acknowledge)收到通知
0000 01110770x07BEL (bell)响铃
0000 100001080x08BS (backspace)退格
0000 100101190x09HT (horizontal tab)水平制表符
0000 1010012100x0ALF (NL line feed, new line)换行键
0000 1011013110x0BVT (vertical tab)垂直制表符
0000 1100014120x0CFF (NP form feed, new page)换页键
0000 1101015130x0DCR (carriage return)回车键
0000 1110016140x0ESO (shift out)不用切换
0000 1111017150x0FSI (shift in)启用切换
0001 0000020160x10DLE (data link escape)数据链路转义
0001 0001021170x11DC1 (device control 1)设备控制1
0001 0010022180x12DC2 (device control 2)设备控制2
0001 0011023190x13DC3 (device control 3)设备控制3
0001 0100024200x14DC4 (device control 4)设备控制4
0001 0101025210x15NAK (negative acknowledge)拒绝接收
0001 0110026220x16SYN (synchronous idle)同步空闲
0001 0111027230x17ETB (end of trans. block)结束传输块
0001 1000030240x18CAN (cancel)取消
0001 1001031250x19EM (end of medium)媒介结束
0001 1010032260x1ASUB (substitute)代替
0001 1011033270x1BESC (escape)换码(溢出)
0001 1100034280x1CFS (file separator)文件分隔符
0001 1101035290x1DGS (group separator)分组符
0001 1110036300x1ERS (record separator)记录分隔符
0001 1111037310x1FUS (unit separator)单元分隔符
0010 0000040320x20(space)空格
0010 0001041330x21!叹号
0010 0010042340x22"双引号
0010 0011043350x23#井号
0010 0100044360x24$美元符
0010 0101045370x25%百分号
0010 0110046380x26&和号
0010 0111047390x27单引号
0010 1000050400x28(开括号
0010 1001051410x29)闭括号
0010 1010052420x2A*星号
0010 1011053430x2B+加号
0010 1100054440x2C,逗号
0010 1101055450x2D-减号/破折号
0010 1110056460x2E.句号
0010 1111057470x2F/斜杠
0011 0000060480x300字符0
0011 0001061490x311字符1
0011 0010062500x322字符2
0011 0011063510x333字符3
0011 0100064520x344字符4
0011 0101065530x355字符5
0011 0110066540x366字符6
0011 0111067550x377字符7
0011 1000070560x388字符8
0011 1001071570x399字符9
0011 1010072580x3A:冒号
0011 1011073590x3B;分号
0011 1100074600x3C<小于
0011 1101075610x3D=等号
0011 1110076620x3E>大于
0011 1111077630x3F?问号
0100 00000100640x40@电子邮件符号
0100 00010101650x41A大写字母A
0100 00100102660x42B大写字母B
0100 00110103670x43C大写字母C
0100 01000104680x44D大写字母D
0100 01010105690x45E大写字母E
0100 01100106700x46F大写字母F
0100 01110107710x47G大写字母G
0100 10000110720x48H大写字母H
0100 10010111730x49I大写字母I
010010100112740x4AJ大写字母J
0100 10110113750x4BK大写字母K
0100 11000114760x4CL大写字母L
0100 11010115770x4DM大写字母M
0100 11100116780x4EN大写字母N
0100 11110117790x4FO大写字母O
0101 00000120800x50P大写字母P
0101 00010121810x51Q大写字母Q
0101 00100122820x52R大写字母R
0101 00110123830x53S大写字母S
0101 01000124840x54T大写字母T
0101 01010125850x55U大写字母U
0101 01100126860x56V大写字母V
0101 01110127870x57W大写字母W
0101 10000130880x58X大写字母X
0101 10010131890x59Y大写字母Y
0101 10100132900x5AZ大写字母Z
0101 10110133910x5B[开方括号
0101 11000134920x5C|反斜杠
0101 11010135930x5D]闭方括号
0101 11100136940x5E^脱字符
0101 11110137950x5F_下划线
0110 00000140960x60`开单引号
0110 00010141970x61a小写字母a
0110 00100142980x62b小写字母b
0110 00110143990x63c小写字母c
0110 010001441000x64d小写字母d
0110 010101451010x65e小写字母e
0110 011001461020x66f小写字母f
0110 011101471030x67g小写字母g
0110 100001501040x68h小写字母h
0110 100101511050x69i小写字母i
0110 101001521060x6Aj小写字母j
0110 101101531070x6Bk小写字母k
0110 110001541080x6Cl小写字母l
0110 110101551090x6Dm小写字母m
0110 111001561100x6En小写字母n
0110 111101571110x6Fo小写字母o
0111 000001601120x70p小写字母p
0111 000101611130x71q小写字母q
0111 001001621140x72r小写字母r
0111 001101631150x73s小写字母s
0111 010001641160x74t小写字母t
0111 010101651170x75u小写字母u
0111 011001661180x76v小写字母v
0111 011101671190x77w小写字母w
0111 100001701200x78x小写字母x
0111 100101711210x79y小写字母y
0111 101001721220x7Az小写字母z
0111 101101731230x7B{开花括号
0111 110001741240x7C
0111 110101751250x7D}闭花括号
0111 111001761260x7E~波浪号
0111 111101771270x7FDEL (delete)删除

相关文章:

PostgreSQL最常用数据类型-重点说明自增主键处理

简介 PostgreSQL提供了非常丰富的数据类型&#xff0c;我们平常使用最多的基本就3类&#xff1a; 数字类型字符类型时间类型 这篇文章重点介绍这3中类型&#xff0c;因为对于高并发项目还是推荐&#xff1a;尽量使用简单类型&#xff0c;把运算和逻辑放在应用中&#xff0c;…...

androidstudio 最新继承 proto kts 方式

在Android Studio中&#xff0c;如果你使用的是Kotlin DSL&#xff08;.kts文件&#xff09;来配置你的Gradle项目&#xff0c;并且你想集成Protocol Buffers&#xff08;Proto&#xff09;&#xff0c;你需要稍微调整你的配置方式。以下是如何在Kotlin DSL中配置Proto集成的步…...

【STM32学习】TB6612FNG驱动芯片的学习,驱动电路的学习

目录 1、TB6612电机驱动芯片 1.1如下是芯片的引脚图&#xff1a; 1.2如下图是电机的控制逻辑&#xff1a; 1.3MOS管运转逻辑 1.3典型应用电路 2、H桥驱动电路 2.1、单极模式 2.2、双极模式 2.3、高低端MOS管导通条件 2.4、H桥电路设计 2.5、自举电路 3、电气特性 3…...

【AI战略思考13】克服懒惰,保持专注,提升效率,不再焦虑

【AI论文解读】【AI知识点】【AI小项目】【AI战略思考】【AI日记】 引言 我发现自己最近非常懒惰&#xff0c;浪费了很多时间&#xff0c;也容易分心&#xff0c;不够专注&#xff0c;效率低下&#xff0c;且每天都有点焦虑&#xff0c;因此制定了下面的要求和作息时间表。 目…...

基于Vue3+Element Plus 实现多表单校验

使用场景 表单校验在日常的开发需求中是一种很常见的需求&#xff0c;通常在提交表单发起请求前校验用户输入是否符合规则&#xff0c;通常只需formRef.value.validate()即可校验&#xff0c;但是&#xff0c;例如一些多步骤表单、动态表单、以及不同的用户角色可能看到不同的表…...

“岗位复合化、技能层次化” 高职大数据技术专业人才培养实践

在全球数字化浪潮的推动下&#xff0c;大数据技术已经成为引领社会进步和经济发展的核心动力。随着《关于深化现代职业教育体系建设改革的意见》等系列指导问文件的发布&#xff0c;我国高职大数据技术专业的教育正迎来全新机遇与挑战。这些政策不仅明确了职业教育改革的方向&a…...

Day2 生信新手笔记: Linux基础

一、基础知识 1.1 服务器 super computer 或 server 1.2 组学数据分析 组学数据&#xff1a;如基因组学、转录组学、蛋白质组学等&#xff1b; 上游分析&#xff1a;主要涉及原始数据的获取和初步处理&#xff0c;计算量大&#xff0c;消耗的资源较多&#xff0c;在服务器完…...

AI开发-数据可视化库-Seaborn

1 需求 概述 Seaborn 是一个基于 Python 的数据可视化库&#xff0c;它建立在 Matplotlib 之上。其主要目的是使数据可视化更加美观、方便和高效。它提供了高层次的接口和各种美观的默认主题&#xff0c;能够帮助用户快速创建出具有吸引力的统计图表&#xff0c;用于数据分析和…...

如何把Qt exe文件发送给其他人使用

如何把Qt exe文件发送给其他人使用 1、先把 Debug改成Release2、重新构建项目3、运行项目4、找到release文件夹5、新建文件夹&#xff0c;存放exe文件6、打开qt控制台串口7、下载各种文件8、压缩&#xff0c;发送压缩包给别人 1、先把 Debug改成Release 2、重新构建项目 3、运行…...

力扣103.二叉树的锯齿形层序遍历

题目描述 题目链接103. 二叉树的锯齿形层序遍历 给你二叉树的根节点 root &#xff0c;返回其节点值的 锯齿形层序遍历 。&#xff08;即先从左往右&#xff0c;再从右往左进行下一层遍历&#xff0c;以此类推&#xff0c;层与层之间交替进行&#xff09;。 示例 1&#xff…...

MOH: MULTI-HEAD ATTENTION AS MIXTURE-OFHEAD ATTENTION

当前的问题 多头注意力使用多个头部可以提高模型的精度。然而&#xff0c;并不是所有的注意力头都具有同样的重要性。一些研究表明&#xff0c;许多注意力头可以被修剪而不影响准确性。 此外&#xff0c;在多头注意中&#xff0c;每个注意头并行操作&#xff0c;最终输出是所…...

Linux的文件系统

这里写目录标题 一.文件系统的基本组成索引节点目录项文件数据的存储扇区三个存储区域 二.虚拟文件系统文件系统分类进程文件表读写过程 三.文件的存储连续空间存放方式缺点 非连续空间存放方式链表方式隐式链表缺点显示链接 索引数据库缺陷索引的方式优点&#xff1a;多级索引…...

力扣78题详解:C语言实现子集问题

力扣78题详解&#xff1a;C语言实现子集问题 题目描述 给定一个不含重复元素的整数数组 nums&#xff0c;返回其所有可能的子集&#xff08;幂集&#xff09;。 说明&#xff1a;解集不能包含重复的子集&#xff0c;顺序无关。 示例 输入&#xff1a;nums [1,2,3] 输出&am…...

按行数据拆分到工作表-Excel易用宝

有这样一份工作表&#xff0c;现在要对工作表按指定行数进行拆分&#xff0c;如果你还在选择数据区域复制粘贴到每个工作表中&#xff0c;那这样的效率也太低了。 按指定行数拆分工作表&#xff0c;就用易用宝。 单击Excel易用宝&#xff0c;合并与拆分&#xff0c;拆分工作表…...

.net core 创建linux服务,并实现服务的自我更新

目录 创建服务创建另一个服务&#xff0c;用于执行更新操作给你的用户配置一些systemctl命令权限 创建服务 /etc/systemd/system下新建服务配置文件&#xff1a;yourapp.service&#xff0c;内容如下&#xff1a; [Unit] Descriptionyourapp Afternetwork.target[Service] Ty…...

无人机的起降装置:探索起飞和降落的秘密 !

一、起降系统的运行方式 起飞方式 垂直起飞&#xff1a;小型无人机通常采用垂直起飞方式&#xff0c;利用螺旋桨产生的升力直接从地面升起。这种方式适用于空间有限或需要快速起飞的场景。 跑道起飞&#xff1a;大型无人机或需要较长起飞距离的无人机&#xff0c;可能会采用…...

Apache Airflow 快速入门教程

Apache Airflow已经成为Python生态系统中管道编排的事实上的库。与类似的解决方案相反&#xff0c;由于它的简单性和可扩展性&#xff0c;它已经获得了普及。在本文中&#xff0c;我将尝试概述它的主要概念&#xff0c;并让您清楚地了解何时以及如何使用它。 Airflow应用场景 …...

数学题转excel;数学题库;数学试卷转excel;大风车excel

一、数学试卷转excel 有些需要刷题的朋友&#xff0c;需要将题库数学题转为excel格式&#xff0c;便于管理 前端时间帮一位朋友实现了数学题转excel&#xff0c;包括选择题、填空题、分析题 示例&#xff1a; 二、问题 数学题是最难以处理的试题&#xff0c;理由如下 1、有…...

【C++】类和对象(下)

目录 前言 一、再探构造函数 二、类型转换 三、static 成员 四、友元 五、内部类 六、匿名对象 七、对象拷贝时的编译器优化 总结 前言 本文主要内容&#xff1a;构造函数的再探--初始化列表、内置类型与自定义类型之间的转换、类的static成员、友元、内部类、匿名对…...

vue多页面应用集成时权限处理问题

在多页面应用&#xff08;MPA&#xff09;中&#xff0c;权限管理通常会涉及到每个页面的访问控制、身份验证、以及权限校验。以下是几种常见的权限处理方式&#xff1a; 1. 前端路由权限控制 原理&#xff1a;虽然是多页面应用&#xff0c;通常每个页面会独立加载和渲染&…...

输出保留3位小数的浮点数

输出保留3位小数的浮点数 C语言代码C代码Java代码Python代码 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 读入一个单精度浮点数&#xff0c;保留3位小数输出这个浮点数。 输入 只有一行&#xff0c;一个单精度浮点数。 输出 也只有一…...

openssl的运用

一、概述 Opssl是一个用于TLS/SSL协议的工具包&#xff0c;也是一个通用密码库。 包含了国密sm2 sm3 sm4&#xff0c;包含了对称加密&#xff0c;非对称加密&#xff0c;单项散列&#xff0c;伪随机、签名&#xff0c;密码交换&#xff0c;证书等一些算法库。 为了深层次的学习…...

C++STL之vector(超详细)

CSTL之vector 1.vector基本介绍2.vector重要接口2.1.构造函数2.2.迭代器2.3.空间2.3.1.resize2.3.2.capacity 2.4.增删查找 3.迭代器失效4.迭代器分类 &#x1f31f;&#x1f31f;hello&#xff0c;各位读者大大们你们好呀&#x1f31f;&#x1f31f; &#x1f680;&#x1f68…...

RabbitMQ消息可靠性保证机制5--消息幂等性处理

RabbitMQ层面有实现“去重机制”来保证“恰好一次”吗&#xff1f;答案是没并没有&#xff0c;而且现在主流的消息中间件都没有实现。 一般解决重复消息的办法是&#xff1a;在消费端让我们消费消息操作具有幂等性。 幂等性问题并不是消息系统独有&#xff0c;而是&#xff0…...

24/12/1 算法笔记<强化学习> 创建Maze交互

我们今天制作一个栅格的游戏。 我们直接上代码教学。 1.载入库和查找相应的函数版本 import numpy as np import time import sysif sys.version_info.major 2:import Tkinter as tk else:import tkinter as tk 2.设置长宽和单元格大小 UNIT 40 MAZE_H 4 MAZE_W 4 3.初始…...

c++:模版 template

一、模版 1.格式&#xff1a; template <typname T> 2.实现 2.1自动推导 模板只对紧跟在后面的第一行代码有效&#xff0c;如果后面还想定义模板函数需要重新定义模板 #include <iostream> #include <string>template <typename T> void Print(T v…...

javascript切换类、删除类、修改类以及增加类

在JavaScript中&#xff0c;操作DOM元素的类&#xff08;class&#xff09;是一个常见的操作。以下是一些基本的方法来切换类、删除类、修改类以及增加内联样式&#xff1a; 切换类&#xff08;Toggle Class&#xff09; 切换类意味着如果类存在则移除它&#xff0c;如果不存…...

区块链学习笔记(2)--区块链的交易模型part1

模型基础 区块链的tx分为两种模型&#xff0c;分别是比特币为代表的UTXO&#xff08;Unspent Transaction Output&#xff09;模型&#xff0c;和以太坊为代表的Account模型。前者适用于货币记账&#xff0c;后者适用于链上应用。 UTXO模型 类似于现金的交易模型 一个tx包含…...

反射知识总结

狂神说 反射的功能&#xff1a; 类加载内存分析 类加载的时候&#xff0c;class对象就形成了。 类无论有多少对象&#xff0c;class对象只有一个。 获取类对象三种方式 反射&#xff0c;就是通过api获取一个类的类对象&#xff1a; 有三种方式&#xff1a; 方法一&#xf…...

selenium部署分布式 UI 自动化测试环境-Docker

一、根据selenium/hub官网的配置信息&#xff0c;进行配置。 How to run this image The Hub and Nodes will be created in the same network and they will recognize each other by their container name. A Docker network⁠ needs to be created as a first step.Create …...

算法刷题Day5: BM52 数组中只出现一次的两个数字

描述&#xff1a; 一个整型数组里除了两个数字只出现一次&#xff0c;其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。 要求&#xff1a;空间复杂度 O(1)&#xff0c;时间复杂度O(n)。 题目传送门 is here 思路&#xff1a; 方法一&#xff1a;最简单的思路就…...

使用docker-compose部署搜索引擎ElasticSearch6.8.10

背景 Elasticsearch 是一个开源的分布式搜索和分析引擎&#xff0c;基于 Apache Lucene 构建。它被广泛用于实时数据搜索、日志分析、全文检索等应用场景。 Elasticsearch 支持高效的全文搜索&#xff0c;并提供了强大的聚合功能&#xff0c;可以处理大规模的数据集并进行快速…...

多线程篇-5--线程分类(线程类型,springboot中常见线程类型,异步任务线程)

常见的线程类型包括用户线程&#xff08;User Threads&#xff09;、守护线程&#xff08;Daemon Threads&#xff09;、主线程&#xff08;Main Thread&#xff09;、工作线程&#xff08;Worker Threads&#xff09;和线程池中的线程。 一、用户线程&#xff08;User Thread…...

详解高斯消元

详解高斯消元 好东西,可以求所有一次方程组的解。 \color {red} 好东西,可以求所有一次方程组的解。 好东西,可以求所有一次方程组的解。 前置知识 一般消元法的公理: 两方程互换,解不变; 一方程乘以非零数 k k k,解不变; 一方程乘以数 k k k加上另一方程,解不变。 …...

【Python网络爬虫笔记】5-(Request 带参数的get请求) 爬取豆瓣电影排行信息

目录 1.抓包工具查看网站信息2.代码实现3.运行结果 1.抓包工具查看网站信息 请求路径 url:https://movie.douban.com/typerank请求参数 页面往下拉&#xff0c;出现新的请求结果&#xff0c;参数start更新&#xff0c;每次刷新出20条新的电影数据 2.代码实现 # 使用网络爬…...

泷羽sec- shell编程(8) until循环以及函数基本创建调用 学习笔记

声明&#xff01; 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&a…...

Apache Flink从Kafka中消费商品数据,并进行商品分类的数量统计题

使用Apache Flink从Kafka中消费商品数据&#xff0c;并进行商品分类的数量统计是一个典型的流处理任务。以下是一个详细的步骤指南和示例代码&#xff0c;帮助你实现这一功能。 ### 前提条件 1. **安装Flink**&#xff1a;确保你的环境中已经安装了 Apache Flink。 2. **安装…...

Ubuntu 安装 MariaDB

安装 MariaDB具体步骤 1、更新软件包索引&#xff1a; sudo apt update2、安装 MariaDB 服务器&#xff1a; sudo apt install mariadb-server3、启动 MariaDB 服务&#xff08;如果未自动启动&#xff09;&#xff1a; sudo systemctl start mariadb4、设置 MariaDB 开机启…...

GPT打字机效果—— fetchEventSouce进行sse流式请求

EventStream基本用法 与 WebSocket 不同的是&#xff0c;服务器发送事件是单向的。数据消息只能从服务端到发送到客户端&#xff08;如用户的浏览器&#xff09;。这使其成为不需要从客户端往服务器发送消息的情况下的最佳选择。 const evtSource new EventSource(“/api/v1/…...

Leetcode 3373. Maximize the Number of Target Nodes After Connecting Trees II

Leetcode 3373. Maximize the Number of Target Nodes After Connecting Trees II 1. 接替思路2. 代码实现 题目链接&#xff1a;3373. Maximize the Number of Target Nodes After Connecting Trees II 1. 接替思路 这一题和前一题Leetcode 3372其实整体思路上并没有啥太大…...

JS的魔法三角:constructor、prototype与__proto__

在JavaScript中&#xff0c;constructor、prototype和__proto__是与对象创建和继承机制紧密相关的三个概念。理解它们之间的关系对于掌握JavaScript的面向对象编程至关重要。下面将详细介绍这个魔法三角&#xff1a; 1. constructor 定义&#xff1a;constructor是一个函数&am…...

用c语言完成俄罗斯方块小游戏

用c语言完成俄罗斯方块小游戏 这估计是你在编程学习过程中的第一个小游戏开发&#xff0c;怎么说呢&#xff0c;在这里只针对刚学程序设计的学生&#xff0c;就是说刚接触C语言没多久&#xff0c;有一点功底的学生看看&#xff0c;简陋的代码&#xff0c;简陋的实现&#xff0…...

Leetcode打卡:N皇后

执行结果&#xff1a;通过 题目&#xff1a;51 N皇后 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#…...

位运算在嵌入式系统开发中的应用

目录 一、数据存储与节省 “绝技” 1.1. 传感器数据存储挑战 1.2. 位运算解决方案 1.2.1. 数据整合 1.2.2. 数据提取 1.3. 收益分析 二、硬件控制 “精准操纵术” 2.1. 位运算操控硬件寄存器的实例 2.2. 位运算在硬件控制中的优势 2.3. 电机驱动芯片寄存器控制示例 …...

livekit 服务部署

本地起 1. 拉取生成文件镜像 sudo docker pull livekit/generate 2. 生成配置文件 sudo docker run --rm -v $PWD:/output livekit/generate --local (记住输出信息) 3. 拉取livekit/livekit-server sudo docker pull livekit/livekit-server 4. 开始运行服务 sudo docker run…...

笔记:visual studio2022编译 和 运行 VTK9.4.0

一、下载源码 VTK官网下载对应源码。 Download | VTKhttps://vtk.org/download/ 二、编译动态库&#xff08;基于Win11 24h&#xff09; 1. 用VS打开VTK源码的CMakeLists.txt&#xff0c;等待项目配置完成。 生成完毕如图 2.生成动态库&#xff0c;点击全部生成&#xff0c…...

【Linux | 计网】TCP协议深度解析:从连接管理到流量控制与滑动窗口

目录 前言&#xff1a; 1、三次握手和四次挥手的联系&#xff1a; 为什么挥手必须要将ACK和FIN分开呢&#xff1f; 2.理解 CLOSE_WAIT 状态 CLOSE_WAIT状态的特点 3.FIN_WAIT状态讲解 3.1、FIN_WAIT_1状态 3.2、FIN_WAIT_2状态 3.3、FIN_WAIT状态的作用与意义 4.理解…...

Qt Sensors 传感器控制介绍篇

文章目录 Qt Sensors 模块介绍前言 什么是 Qt Sensors&#xff1f;主要特点&#xff1a; 支持的传感器类型Qt Sensors 的核心组件应用场景优势总结 Qt Sensors 模块介绍 前言 随着现代硬件设备的不断发展&#xff0c;传感器已成为许多设备&#xff08;如智能手机、平板电脑和…...

探索3D世界:使用 lib3ds 读取和解析 3DS 文件

在3D图形开发中&#xff0c;读取和解析3DS文件是创建和渲染3D场景的第一步。3DS&#xff08;3D Studio&#xff09;文件格式是一种广泛使用的3D模型文件格式&#xff0c;它包含了多种类型的数据&#xff0c;用于描述3D场景中的物体、材质、相机、灯光和动画等。lib3ds 是一个开…...

【开源免费】基于SpringBoot+Vue.JS服装生产管理系统(JAVA毕业设计)

博主说明&#xff1a;本文项目编号 T 066 &#xff0c;文末自助获取源码 \color{red}{T066&#xff0c;文末自助获取源码} T066&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析…...