PostgreSQL有意思的现象:支持不带列的表

1、前言

以前从没有试过建一张表,不带任何列。在PG中却支持这种语法。这是个什么鬼?

最近,把PG源码扒了下,简单浏览了下最近的一些merge。其中有一个fix:

eeb0ebad79 ("Fix the initial sync tables with no columns.", 2023-11-22)

    Fix the initial sync tables with no columns.

    The copy command formed for initial sync was using parenthesis for tables
    with no columns leading to syntax error. This patch avoids adding
    parenthesis for such tables.

    Reported-by: Justin G
    Author: Vignesh C
    Reviewed-by: Peter Smith, Amit Kapila
    Backpatch-through: 15
    Discussion: http://postgr.es/m/18203-df37fe354b626670@postgresql.org

简单的说,是它考虑到一张表,在初始SYNC时,有可能没有任何列。按自己的印象,别的DBMS好像没有支持这种语法的。

2、简单验证

如果我们在SQLSERVER哪怕是最新版2022上试一下,

https://dbfiddle.uk/1n2I7Bj9
create table tab_no_col();
-- 立马报错
Msg 102 Level 15 State 1 Line 1
Incorrect syntax near ')'.

图片

切到MySQL, 也不支持这种语法:

https://dbfiddle.uk/xZPbFq4N
create table tab_no_col();
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 1

图片

再试下Oracle, 发现也不支持。哪怕是23C。

https://dbfiddle.uk/-F2lutlX
create table tab_no_col();
ORA-00931: missing identifier

图片

3、PostgreSQL中的行为

我们就以PostgreSQL 14为例 :

postgres=# create table tab_no_col();
CREATE TABLE
postgres=# insert into tab_no_col default values;
INSERT 0 1
postgres=# select * from tab_no_col;
--
(1 row)

postgres=# insert into tab_no_col default values;
INSERT 0 1
postgres=# insert into tab_no_col default values;
INSERT 0 1
postgres=# insert into tab_no_col default values;
INSERT 0 1
postgres=# select count(*) from tab_no_col;
 count 
-------
     4
(1 row)

postgres=# select * from tab_no_col;
--
(4 rows)

虽然没有真正的值,但是却一样可以插入相关的值,并得到相应的行数。

根据这种特性,我们甚至可以预先建一张没有任何列的表,然后,插入一些列。看看:

postgres=# alter table tab_no_col add col2 varchar(32) null;
ALTER TABLE

postgres=# select * from tab_no_col;
 col2 
------




(4 rows)

更新一些值:

postgres=# update tab_no_col set col2 = 'a_' || ctid || '_' || xmin;
UPDATE 4
postgres=# select * from tab_no_col;
    col2     
-------------
 a_(0,1)_785
 a_(0,2)_786
 a_(0,3)_787
 a_(0,4)_788
(4 rows)

这种功能,也许最大的好处就是先建一张表(空列),然后可以动态的增加或改变一些列。利用FOR循环时,直接"(" 和 ”)" 做匹配,而不用考虑列数是否真正大于0。

反正CREATE TABLE ABC(, 即算完全是空的,语法上它也不会报错。

相关推荐

  1. PostgreSQL 支持字段类型

    2023-12-08 01:36:01       42 阅读
  2. 有意思、好用免费API分享

    2023-12-08 01:36:01       29 阅读
  3. PostgreSQL工具介绍

    2023-12-08 01:36:01       9 阅读
  4. PostgreSQL查看大小

    2023-12-08 01:36:01       6 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-08 01:36:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-08 01:36:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-08 01:36:01       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-08 01:36:01       20 阅读

热门阅读

  1. qt反射基础

    2023-12-08 01:36:01       31 阅读
  2. android 13.0 framework禁用系统所有通知

    2023-12-08 01:36:01       37 阅读
  3. Linux下超轻量级Rust开发环境搭建:一、安装Rust

    2023-12-08 01:36:01       38 阅读
  4. python pandas dataframe常用数据处理总结

    2023-12-08 01:36:01       37 阅读
  5. 纯C读取文件实现解析H264裸流每一帧数据

    2023-12-08 01:36:01       45 阅读
  6. Redisson

    2023-12-08 01:36:01       43 阅读
  7. 算法 拓扑序列

    2023-12-08 01:36:01       29 阅读
  8. Redis默认序列化方式乱码原因及解决办法

    2023-12-08 01:36:01       43 阅读
  9. 计算机网络——传输层

    2023-12-08 01:36:01       39 阅读
  10. python模块 — json

    2023-12-08 01:36:01       42 阅读
  11. TCP_NODELAY与TCP通信效率

    2023-12-08 01:36:01       43 阅读
  12. 【算法】合并K个升序链表

    2023-12-08 01:36:01       41 阅读
  13. Dynamo学习使用的网站

    2023-12-08 01:36:01       44 阅读