PostgreSQL中的序列名很长很长怎么办
原创 SeanHe 数据库杂记 2023-05-06 06:01 发表于上海PostgreSQL中的序列名很长很长怎么办
tag: PostgreSQL, 数据库移植
1.前言
我们回忆一下,PostgreSQL好像有对象名不超过63个字符的默认限制。详见: current/limit.html
而序列名可能是由系统自动生成的那种。比如一个表定义了某一列是serial之类的,它会隐含创建一个sequence。
我们来通过简单的实例看看这是啥样的情形?本能的,你可能以为,如果表名很长,序列名是不是超长了?
2.实际验证
2.1 正常的示例:
1postgres=# create table test(id bigserial, col2 text);
2CREATE TABLE
3postgres=# \d+ test
4 Table "public.test"
5 Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description
6--------+--------+-----------+----------+----------------------------------+----------+-------------+--------------+-------------
7 id | bigint | | not null | nextval('test_id_seq'::regclass) | plain | | |
8 col2 | text | | | | extended | | |
9Access method: heap
10
11postgres=# \d+ test_id_seq
12 Sequence "public.test_id_seq"
13 Type | Start | Minimum | Maximum | Increment | Cycles? | Cache
14--------+-------+---------+---------------------+-----------+---------+-------
15 bigint | 1 | 1 | 9223372036854775807 | 1 | no | 1
16Owned by: public.test.id
在这个例子中,我们建了一个普通的表test,列: id是一个8位序列类型,这样系统会为表test自动生成序列:test_id_seq,它的名字不过就是11。是<表名>_<列名>_seq,也就是len(序列名) = len(表名) + len(seq列名)+5。
这种情况发生在后者加起来不超过63的情况。
接下来,我们构造一两个边界的例子看看是什么样子的。
2.2 列名很长
建了下面这张表,让序列对应的列名长为63.
1postgres=# create table test1(col123456789012345678901234567890123456789012345678901234567890 bigserial, col2 text);
2CREATE TABLE
3postgres=# \d+ test1
4 Table "public.test1"
5 Column | Type | Collation | Nullable |
6 Default | Storage | Compression | Stats target | Description
7-----------------------------------------------------------------+--------+-----------+----------+--------------------------------------
8------------------------------------------------+----------+-------------+--------------+-------------
9 col123456789012345678901234567890123456789012345678901234567890 | bigint | | not null | nextval('test1_col1234567890123456789
100123456789012345678901234567890_seq'::regclass) | plain | | |
11 col2 | text | | |
12 | extended | | |
13Access method: heap
我们能看到,生成的序列名为:test1_col12345678901234567890123456789012345678901234567890_seq,总长也是63。
将列名最末字符换成1,结果就是:
1postgres=# create table test1(col123456789012345678901234567890123456789012345678901234567891 bigserial, col2 text);
2CREATE TABLE
3postgres=# \d+ test1
4 Table "public.test1"
5 Column | Type | Collation | Nullable |
6 Default | Storage | Compression | Stats target | Description
7-----------------------------------------------------------------+--------+-----------+----------+--------------------------------------
8------------------------------------------------+----------+-------------+--------------+-------------
9 col123456789012345678901234567890123456789012345678901234567891 | bigint | | not null | nextval('test1_col1234567890123456789
100123456789012345678901234567890_seq'::regclass) | plain | | |
11 col2 | text | | |
12 | extended | | |
13Access method: heap
生成的序列名为:test1_col12345678901234567890123456789012345678901234567890_seq,总长也是63。
名字与前边那个是一样的,对比一下看下图:
反向推理:它是把 {表名_截短后的列名_seq}构造成新的序列名。截短的原则是,从最末尾的子串进行截短。超长的部分都截掉。
2.3 表名很长
我们再看看如下示例,表名长度为63:tab123456789012345678901234567890123456789012345678901234567890
生成的序列名为:tab1234567890123456789012345678901234567890123_id1234567890_seq, 长度仍然为63.
1postgres=# create table tab123456789012345678901234567890123456789012345678901234567890(id1234567890 bigserial, col2 text);
2CREATE TABLE
3postgres=# \d+ tab123456789012345678901234567890123456789012345678901234567890
4 Table "public.tab123456789012345678901234567890123456789012345678901234567890"
5 Column | Type | Collation | Nullable | Default | S
6torage | Compression | Stats target | Description
7--------------+--------+-----------+----------+--------------------------------------------------------------------------------------+--
8--------+-------------+--------------+-------------
9 id1234567890 | bigint | | not null | nextval('tab1234567890123456789012345678901234567890123_id1234567890_seq'::regclass) | p
10lain | | |
11 col2 | text | | | | e
12xtended | | |
13Access method: heap
对比一下这两个名字:
看起来,生成的名字是:{截短后表名_列名_seq}。如果是这样,依据这个,构造一个不同的表名,看看是什么样的?
比如表名是:tab123456789012345678901234567890123456789012345678901234567891,即最末一个字符不同。我们看看:
1postgres=# create table tab123456789012345678901234567890123456789012345678901234567891(id1234567890 bigserial, col2 text);
2CREATE TABLE
3postgres=# \d+ tab123456789012345678901234567890123456789012345678901234567891
4 Table "public.tab123456789012345678901234567890123456789012345678901234567891"
5 Column | Type | Collation | Nullable | Default | S
6torage | Compression | Stats target | Description
7--------------+--------+-----------+----------+--------------------------------------------------------------------------------------+--
8--------+-------------+--------------+-------------
9 id1234567890 | bigint | | not null | nextval('tab123456789012345678901234567890123456789012_id1234567890_seq1'::regclass) | p
10lain | | |
11 col2 | text | | | | e
12xtended | | |
13Access method: heap
在这个我们想像的”反例“中,
表名:
tab123456789012345678901234567890123456789012345678901234567891
序列名:
tab123456789012345678901234567890123456789012_id1234567890_seq1
与上边的示例四个名字对比一下:
反推一下,情况也明了了,当它发现序列名可能重复时,会在seq后边加上计数器,然后前边的截断重新调整一下就实现了唯一性。这个算法看来不错。
2.4 表名和列名都很长
我们一步到位。表名:
tab123456789012345678901234567890123456789012345678901234567892 长度:63
序列列名:
col123456789012345678901234567890123456789012345678901234567890 长度:63
两者都很长。
1postgres=# create table tab123456789012345678901234567890123456789012345678901234567892(col123456789012345678901234567890123456789012345678901234567890 bigserial, col2 text);
2CREATE TABLE
3postgres=# \d+ tab123456789012345678901234567890123456789012345678901234567892
4 Table "public.tab123456789012345678901234567890123456789
5012345678901234567892"
6 Column | Type | Collation | Nullable |
7 Default | Storage | Compression | Stats target | Description
8-----------------------------------------------------------------+--------+-----------+----------+--------------------------------------
9------------------------------------------------+----------+-------------+--------------+-------------
10 col123456789012345678901234567890123456789012345678901234567890 | bigint | | not null | nextval('tab12345678901234567890123456_col12345678901234567890123456_seq'::regclass) | plain | | |
11 col2 | text | | |
12 | extended | | |
13Access method: heap
我们看看生成的序列名:tab12345678901234567890123456_col12345678901234567890123456_seq 长度:63
1表名:tab123456789012345678901234567890123456789012345678901234567892
2列表:col123456789012345678901234567890123456789012345678901234567890
3序列:tab12345678901234567890123456_col12345678901234567890123456_seq
从现象上看,它从表名中拿了30个字符,从列名中拿了前30个字符。这个应该也有一定的选择性算法。
如果我们把上边的表名调整一下,末位改为1. 得到的是下边的结果:
1postgres=# create table tab123456789012345678901234567890123456789012345678901234567891(col123456789012345678901234567890123456789012345678901234567890 bigserial, col2 text)
2;
3CREATE TABLE
4postgres=# \d+ tab123456789012345678901234567890123456789012345678901234567891
5 Table "public.tab123456789012345678901234567890123456789
6012345678901234567891"
7 Column | Type | Collation | Nullable |
8 Default | Storage | Compression | Stats target | Description
9-----------------------------------------------------------------+--------+-----------+----------+--------------------------------------
10------------------------------------------------+----------+-------------+--------------+-------------
11 col123456789012345678901234567890123456789012345678901234567890 | bigint | | not null | nextval('tab12345678901234567890123456_col1234567890123456789012345_seq1'::regclass) | plain | | |
12 col2 | text | | |
13 | extended | | |
14Access method: heap
1表名:tab123456789012345678901234567890123456789012345678901234567891
2列表:col123456789012345678901234567890123456789012345678901234567890
3序列:tab12345678901234567890123456_col1234567890123456789012345_seq1
作为对比,我们发现,它这里仍然以”去重“为思想,然后从总的表名列名全并串里头重新截短。真是妙。
至此,全部验证结束。我们可以大胆放心的使用了。
小结:
PostgreSQL中的对象名长度限制,针对序列类型的序列对象名的自动生成,还是比较巧妙的。我们也不用担心超长的问题。它会根据表名以及对应的列名,有规律的生成序列名。在认为有重复的时候,后缀可能就是_seq1, _seq2。
所以,放心大胆的用吧。只要表名列名都不超长即可。
标签:test1,PostgreSQL,很长,seq,text,col2,表名,序列 From: https://www.cnblogs.com/chuangsi/p/17397402.html