无法在PostgreSQL中创建名为'user'的数据库表

151

似乎PostgreSQL不允许创建名为'user'的数据库表,但是MySQL可以创建这样的表。

这是因为'user'是一个关键词吗?但是Hibernate无法识别任何问题(即使我们设置了PostgreSQLDialect)。


2
是的,user是一个保留关键字。只要不将其用作表名即可。http://www.postgresql.org/docs/9.3/static/sql-keywords-appendix.html - JB Nizet
你可以在postgreSQL中创建一个名为“user”的表。但是我建议您避免使用token关键字作为表/列/变量的名称。 - Houari
非常抱歉,这不是重复的问题。问题是关于PostgreSQL而不是与MySQL有关的事情。谢谢。 - Channa
类似问题:type用作数据库列名 - Basil Bourque
5个回答

222

user是一个保留字,通常不建议将保留字用于标识符(如表名、列名)。

如果您坚持这样做,您必须将表名用双引号括起来:

create table "user" (...);

但是当引用表时,您总是需要使用双引号。此外,表名区分大小写。"user"是不同于"User"的表名。

如果您想节省很多麻烦,请使用其他名称。usersuser_account,...

有关带引号的标识符的更多详细信息,请参阅手册:http://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS


6
适当的翻译是:不要使用需要引用标识符的名称,无论你使用的混淆层是什么。 - user330315
1
不,那不是正确的方法 :) 这会将您的代码与特定数据库及其关键字绑定(而且这个设置可能会更改)。一个实际的解决方案是全局启用转义(虽然我自己没有尝试过),另一个是依靠Hibernate方言分析器(但正如我们看到的那样,它们并不总是能确定我们是否需要转义某些内容)。 - Maksim Gumerov
@MaksimGumerov 的重点是,您不能创建名为 user 的表,因为它受数据库保留。 - IamDOM
1
当然可以 - 使用引号,这是其中一种方法。也许我不应该这样做,但这也是有争议的。更重要的是,我如何创建这样的表格,而这里提出的解决方案(带引号的解决方案)在Hibernate项目中并没有帮助。最初的问题提到了Hibernate,所以答案实际上不能很好地回答它。 - Maksim Gumerov
1
更重要的是(尽管不是建设性的),JPA应该让我们在编写实体类时不必考虑方言,但现在我们正在谈论我无法为Postgres使用一个对Mysql完全有效的表名。塔达!(尽管JPA可以为我们执行必要的名称转义,但它仍然失败了) - Maksim Gumerov
显示剩余4条评论

29

可以使用下面的语法在JPA中指定表名:

@Table(name="\"user\"")

那解决了我的问题。如果没有那个,我会收到“列user0_.id不存在”的错误。 - James Freitas
4
这个对我很有用,但很奇怪的是"user"是一个保留字,几乎在我职业生涯中遇到的每个应用程序中都被用作表名。 - Israelm

17

下划线后缀_

SQL标准明确承诺永远不会在任何名称、关键字或保留字中使用下划线(U+005F LOW LINE)。要自己查看,请搜索规范中的“下划线”一词。

因此,为避免与各种数据库引擎使用的超过一千个关键字和保留字之一发生冲突,我将所有数据库标识符命名为带有下划线的后缀。(是的,真的,我数了一下,超过一千个保留关键字——我数过了。)

将此更改为:

CREATE TABLE user ( … ) ;

...变成这样:

CREATE TABLE user_ ( … ) ;

对于所有数据库名称,包括模式、表、列、索引等,我都有一个习惯:这样做。

我感到更加轻松,因为我已经消除了由命名冲突引起的整个错误和问题类别。

作为额外的好处,这种做法在文档、电子邮件等方面非常清晰,当涉及到编程语言变量user和数据库列user_时,任何带有下划线的内容显然来自数据库方面。


那是一个聪明而简单的举动。 - Alexander Ivanchenko
5
这就是在该领域的真实经验。 - winwin
你如何命名关联表? - undefined

11

我们曾经遇到过同样的问题,我们只是将表名从user更改为app_user,因为我们使用了Hibernate/JPA。我们认为这样做会更容易。 希望这个小修复能帮助其他人。


做了同样的事情。 - Stefan Falk

6
您可以在名称不为 public 的模式中创建表格 user。 例如:
CREATE SCHEMA my_schema;
CREATE TABLE my_schema.user(...);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接