这一直困扰着我一段时间,我无法找到感觉正确的解决方案......
给定一种OO语言,其中对象属性的通常命名约定是camelCased,以及像这样的示例对象:
{
id: 667,
firstName: "Vladimir",
lastName: "Horowitz",
canPlayPiano: true
}
我应该如何在PostgreSQL表中建模这个结构?
主要有三种选择:
他们每个人都有自己的缺点:
不带引号的标识符会自动折叠为小写。这意味着您可以创建一个带有canPlayPiano
列的表,但混合大小写永远不会到达数据库。当您检查表时,该列将始终显示为canplaypiano
- 在psql,pgadmin中,解释结果,错误消息,所有内容。
带引号的标识符保留了它们的大小写,但是一旦你创建它们,你将总是引用它们。 IOW,如果您创建一个包含"canPlayPiano"
列的表格,则SELECT canPlayPiano ...
将失败。这会给所有SQL语句增加许多不必要的噪音。
带下划线的小写名称是明确的,但它们不能很好地映射到应用程序语言正在使用的名称。您必须记住使用不同的名称进行存储(can_play_piano
)和代码(canPlayPiano
)。它还可以防止某些类型的代码自动化,其中属性和数据库列需要命名相同。
所以我陷入了岩石和坚硬的地方(和一块大石头;有三种选择)。无论我做什么,有些部分会感到尴尬。在过去10年左右的时间里,我一直在使用选项3,但我一直希望有更好的解决方案。
我很感激您的任何建议。
PS:我确实意识到案例折叠和引号需求来自哪里 - SQL标准,或者更确切地说是PostgreSQL对标准的改编。我知道它是如何工作的;我对有关最佳实践的建议比对PG如何处理标识符的解释更感兴趣。答案 0 :(得分:28)
鉴于PostgreSQL使用带下划线的不区分大小写的标识符,您是否应该更改应用程序中的所有标识符以执行相同操作?显然不是。那你为什么认为反过来是一个合理的选择?
PostgreSQL中的惯例是通过混合使用标准和用户的长期经验实现的。坚持下去。
如果列名和标识符之间的翻译变得乏味,那么让计算机去做 - 他们擅长这样的事情。我猜几乎所有900万个数据库抽象库都可以做到。如果你有一个动态语言,它将把你所有的两行代码交换到CamelCase中的标识符。
答案 1 :(得分:18)
如果PostgreSQL
中的列与underscores
一致,您可以使用 doule-quotes 来设置别名。
示例:
SELECT my_column as "myColumn" from table;
答案 2 :(得分:0)
我知道这已经很晚了,但是对于一些易于即时翻译的东西,您可以编写一个小的帮助函数,将其保存在您的代码中,如下所示:
函数FormatObjForDb(srcObj){
const newObj = {};
Object.keys(srcObj).forEach(key => newObj[key.toLowerCase()] = srcObj[key]);
return newObj;
}
export const formatObjForDb = FormatObjForDb;