我try 创建名为15909434_user的表,语法如下:

CREATE TABLE 15909434_user ( ... )

这当然会产生错误.然后,在我try 与谷歌进行一些研究后,我发现了一篇很好的文章here,其中描述:

在PostgreSQL中创建对象时,为该对象命名.每个表都有一个名称,每个列都有一个名称,依此类推.PostgreSQL使用单一数据类型定义所有对象名称:name类型.

类型为name的值是63个或更少字符的字符串.名称必须以字母或下划线开头;字符串的其余部分可以包含字母、数字和下划线.

...

如果发现需要创建一个不符合这些规则的对象,可以用双引号将该名称括起来.将名称用引号括起来会创建一个带引号的标识符.例如,您可以创建一个名称为"3.14159"的表——双引号是必需的,但实际上不是名称的一部分(也就是说,它们不存储,也不计入63个字符的限制)...

好的,现在我知道如何使用以下语法解决这个问题(在表名上加双引号):

CREATE TABLE "15909434_user" ( ... )

您可以创建表或列名,例如"15909434_user"user_15909434,但如果不使用双引号,则无法创建以数字开头的表或列名.

因此,我很好奇这背后的原因(除了这是一个惯例).为什么适用这一公约?是为了避免语法限制还是其他原因?

提前感谢您的关注!

推荐答案

它源于原始的sql标准,经过几层间接处理,最终得到identifier start块,这是几个方面之一,但主要是"一个简单的拉丁字母".还有其他一些东西可以使用,但如果你想看到所有细节,请转到http://en.wikipedia.org/wiki/SQL-92并按照实际标准的链接(第85页)

使用非数字标识符介绍人可以使编写解析器来解码sql以执行变得更容易、更快,但使用带引号的表单也可以.


编辑:为什么解析器更容易?

解析器的问题更多地出现在SELECT list子句中,而不是FROM子句中. Select 列表是从表中 Select 的表达式列表,这非常灵活,允许使用简单的列名和数字表达式.考虑以下事项:

SELECT 2e2 + 3.4 FROM ...

如果表名和列名可以以数字开头,那么2e2是列名还是有效数字(数字文字中通常允许e格式),3.4是表"3"和列"4"还是数值3.4

identifiers以简单的拉丁字母(以及其他一些特定的东西)开头的规则意味着,看到2e2的解析器可以快速识别这将是一个数字表达式,这与3.4相同

虽然可以设计一个允许数字前导字符的方案,但这可能会导致更模糊的规则(意见),所以这个规则是一个很好的解决方案.如果你先允许数字,那么它总是需要引用,这可以说不是"干净的".


Disclaimer,我稍微简化了上面的内容,忽略相关名称以保持简短.我对postgres并不完全熟悉,但我已经根据Oracle RDB文档和sql规范仔细判断了上述答案

Postgresql相关问答推荐

如何在Windows中安装sql for golang

Postgis超过2个表的查询在运行时爆炸

使用Spring data jpa和CriteriaQuery在jsonb列中搜索操作

将XML解析从T-SQL迁移到Postgres时出现问题

如何在PostgreSQL中 Select 最近30天内的开始日期?

如何在Postgres中对分区表使用Hibernate验证?

自左联接的POSTGIS更新

IF 块中的 CREATE FUNCTION 语句抛出错误,同时运行它自己的作品

gitlab在ubuntu上安装duplicate schema问题

JPA findBy 字段忽略大小写

PostgreSQL 查询到 Excel 表

如何在 Postgres 中的列上删除唯一约束?

psql:致命:connection requires a valid client certificate

为什么 sqlalchemy 的默认列值不起作用

Postgres jsonbNOT contains运算符

PostgreSQL 获取过go 12 小时的元素

PGError:错误: column of relation does not exist

使用 RPostgreSQL 写入特定模式

PostgreSQL:从转储中恢复数据库 - 语法错误

如何使用 PostgreSQL 在任何列中查找所有具有 NULL 值的行