22

我尝试创建15909434_user使用如下语法命名的表:

CREATE TABLE 15909434_user ( ... )

当然会产生错误。然后,在我尝试用谷歌进行一些研究之后,我在这里找到了一篇很好的文章,它描述了:

当你在 PostgreSQL 中创建一个对象时,你给那个对象一个名字。每个表都有一个名称,每个列都有一个名称,等等。PostgreSQL 使用单一数据类型来定义所有对象名称:name类型。

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

...

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

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

CREATE TABLE "15909434_user" ( ... )

您可以创建表名或列名,例如"15909434_user"and user_15909434,但不能创建以数字开头的表名或列名而不使用双引号。

那么,我很好奇其背后的原因(除了它是一个约定)。为什么应用这个约定?是为了避免语法限制或其他原因吗?

提前感谢您的关注!

4

2 回答 2

29

它来自原始的 sql 标准,通过几层间接最终到达一个标识符开始块,这是几件事之一,但主要是“一个简单的拉丁字母”。还有其他可以使用的东西,但是如果您想查看所有详细信息,请访问http://en.wikipedia.org/wiki/SQL-92并点击实际标准的链接(第 85 页)

使用非数字标识符引入者可以更轻松、更快速地编写解析器来解码 sql 以执行,但引用的形式也可以。


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

解析器的问题更多在于SELECT-list 子句而不是FROM子句。select-list 是从表中选择的表达式列表,它非常灵活,允许简单的列名和数字表达式。考虑以下:

SELECT 2e2 + 3.4 FROM ...

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

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

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


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

于 2013-04-10T04:59:00.493 回答
6

我想这与语法有关。

SELECT 24*DAY_NUMBER as X from MY_TABLE

很好,但如果允许 24 作为列名,则不明确。

添加引号意味着您明确引用标识符而不是常量。所以为了使用它,无论如何你总是必须逃避它。

于 2013-04-10T04:45:18.897 回答