PostgreSQL标识符中的下划线或camelCase,当编程语言使用camelCase时?

Posted

技术标签:

【中文标题】PostgreSQL标识符中的下划线或camelCase,当编程语言使用camelCase时?【英文标题】:Underscores or camelCase in PostgreSQL identifiers, when the programming language uses camelCase? 【发布时间】:2012-07-01 12:20:48 【问题描述】:

这已经困扰了我一段时间,我无法找到一个感觉正确的解决方案......

给定一种对象属性的通常命名约定为驼峰式命名约定的 OO 语言,以及这样的示例对象:


    id: 667,
    firstName: "Vladimir",
    lastName: "Horowitz",
    canPlayPiano: true

我应该如何在 PostgreSQL 表中为这个结构建模?

有三个主要选项:

    不带引号的 camelCase 列名 引用的 camelCase 列名 带下划线的不带引号(小写)的名称

它们各有缺点:

    不带引号的标识符会自动折叠为小写。这意味着您可以创建一个包含canPlayPiano 列的表,但混合大小写永远不会到达数据库。当您检查表时,该列将始终显示为 canplaypiano - 在 psql、pgadmin、解释结果、错误消息等所有内容中。

    带引号的标识符保持大小写,但是一旦您这样创建它们,您将总是必须引用它们。 IOW,如果您创建一个带有"canPlayPiano" 列的表,SELECT canPlayPiano ... 将失败。这给所有 SQL 语句增加了很多不必要的噪音。

    带下划线的小写名称是明确的,但它们不能很好地映射到应用程序语言正在使用的名称。您必须记住为存储 (can_play_piano) 和代码 (canPlayPiano) 使用不同的名称。它还可以防止某些类型的代码自动化,其中属性和数据库列需要命名相同。

所以我被夹在一块石头和一块坚硬的地方(还有一块大石头;有三种选择)之间。不管我做什么,总有一部分会让人觉得尴尬。在过去 10 年左右的时间里,我一直在使用选项 3,但我一直希望有更好的解决方案。

感谢您的任何建议。

PS:我确实知道大小写折叠和引号的需求来自何处——SQL 标准,或者更确切地说是 PostgreSQL 对该标准的改编。我知道它是如何工作的;我对最佳实践的建议比对 PG 如何处理标识符的解释更感兴趣。

【问题讨论】:

即使您使用所有小写字母,我建议您让您的数据库抽象层始终在生成的查询中使用引号将所有标识符包装起来。您无法始终预测新版本中将使用哪些新关键字,因此您可以通过引用来避免名称冲突。 您能分享一下您使用的解决方法吗?我遇到了同样的情况,我在 camelCase 中有对象属性,我需要用下划线模式的表列进行映射。我花了几个小时,但我还没有找到一个好的解决方案。 【参考方案1】:

如果PostgreSQL 中的列使用underscores,则可以使用doule-quotes 放置别名。

例子:

SELECT my_column as "myColumn" from table;

【讨论】:

简单而不居高临下的回答! 鉴于引号还可以解决与当前(和未来)关键字的冲突,这似乎是一个好方法。【参考方案2】:

鉴于 PostgreSQL 使用带下划线的不区分大小写的标识符,您是否应该更改应用程序中的所有标识符以执行相同的操作?显然不是。那么为什么你认为反过来是一个合理的选择呢?

PostgreSQL 中的约定是通过标准合规性和用户的长期经验共同实现的。坚持下去。

如果在列名和标识符之间进行翻译变得乏味,让计算机来做吧——它们擅长这样的事情。我猜几乎所有的 900 万个数据库抽象库都可以做到这一点。如果您使用的是动态语言,则只需两行代码即可将列名交换为 CamelCase 中的标识符。

【讨论】:

我才意识到我从来没有将这个问题标记为已回答...引入一个 ORM 翻译函数一开始并没有觉得很优雅,但事后看来(3-4 年后)这是正确的选择我从来没有后悔过。感谢您的帮助。 在很多情况下这是可以接受的,但它会以性能为代价。我最近花了几个小时调试查询性能,发现超过 50% 的响应时间用于重命名列。当然,这是一个大型数据集,但在当今时代并没有什么疯狂的。我希望这个答案能突出那个小陷阱 根据这个答案,使用域通用的约定。由于 SQL 不区分大小写,并且 sometablename 比 some_table_name 更难阅读,因此常见的约定是蛇形大小写。这实际上可以使 ORM 更容易为您提供友好的上层名称,因为去除下划线并将下划线后面的字母大写是微不足道的。否则,您几乎是在考虑自己定义映射。【参考方案3】:

我知道这已经很晚了,但是对于一些很容易即时翻译的东西,你可以编写一个小的帮助函数,这样就可以在你的代码中使用:

函数 FormatObjForDb(srcObj)

const newObj = ;

Object.keys(srcObj).forEach(key => newObj[key.toLowerCase()] = srcObj[key]);

return newObj;

export const formatObjForDb = FormatObjForDb;

【讨论】:

以上是关于PostgreSQL标识符中的下划线或camelCase,当编程语言使用camelCase时?的主要内容,如果未能解决你的问题,请参考以下文章

python基础语法

java笔记1

C#标识符

JavaScript的基础知识

js--词法结构

第二章变量和运算符知识点整理