可移植SQL:唯一主键

可移植SQL:唯一主键,sql,sql-server,oracle,postgresql,Sql,Sql Server,Oracle,Postgresql,试图开发出在大型RDBMS之间可以移植的东西 问题是如何生成并使用自动递增数字作为表的主键 这里有两个主题 用于生成自动递增数字的机制 如何指定要将其用作 桌子 我正在寻找我认为的当前事态的验证: 不幸的是,该领域的标准化起步较晚,在某些方面仍未实施(作为强制性标准)。这意味着在2013年仍然无法以可移植的方式编写CREATETABLE语句。。。如果您希望它具有自动生成的主键 真的会这样吗 Re(1)。这是标准化的,因为它出现在SQL:2003中。据我所知,要走的路是序列。我相信这是SQL:20

试图开发出在大型RDBMS之间可以移植的东西

问题是如何生成并使用自动递增数字作为表的主键

这里有两个主题

  • 用于生成自动递增数字的机制
  • 如何指定要将其用作 桌子
  • 我正在寻找我认为的当前事态的验证:

    不幸的是,该领域的标准化起步较晚,在某些方面仍未实施(作为强制性标准)。这意味着在2013年仍然无法以可移植的方式编写CREATETABLE语句。。。如果您希望它具有自动生成的主键

    真的会这样吗

    Re(1)。这是标准化的,因为它出现在SQL:2003中。据我所知,要走的路是序列。我相信这是SQL:2003的必修部分,对吗?另一种可能是在SQL:2003中定义的IDENTITY关键字,但据我所知,它是标准的可选部分。。。这意味着像甲骨文这样的关键玩家不会实现它。。。并且仍然可以要求遵守。好的,所以序列是指定的可移植方法,对吗

    Re(2)。数据库供应商以不同的方式实现这一点。在PostgreSQL中,您可以将CREATETABLE语句直接与序列链接,而在Oracle中,您必须创建触发器以确保序列与表一起使用

    因此,我的结论是,如果没有(2)的标准化解决方案,那么所有主要参与者现在都支持序列真的没有多大帮助。我仍然需要为CREATETABLE语句这样简单的语句编写特定于db的代码

    是这样吗

    撇开标准和它们的实现不谈,如果有人有一个可移植的解决方案来解决这个问题,我也会感兴趣,不管从RDBMS最佳实践的角度来看,这是否是一个黑客行为。要使这种解决方案发挥作用,它必须独立于任何应用程序,即它必须是解决问题的数据库,而不是应用程序层。也许如果触发器和序列的概念都可以说是标准化的,那么将两者结合起来的解决方案将是可移植的?

    至于“可移植的创建表语句”:它从数据类型开始:无论布尔、int或long数据类型是否是任何SQL标准的一部分,我都非常欣赏这些类型。PostgreSql支持这些数据类型,Oracle不支持。具有讽刺意味的是,Oracle支持PL/SQL中的布尔值,但不支持将其作为表中的数据类型。甚至在Oracle中,表/列名等的长度也限制为30个字符。因此,即使是最简单的“创建表”也并非总是可移植的

    至于自动生成的主键:我不知道可移植的语法,所以我没有在“createtable”中定义它。当然,这只会延迟问题,并将问题留给insert语句处理。本主题涉及另一个问题:以最有效的方式使用JDBC在插入后获取生成的密钥。这在Oracle和PostgreSql之间有很大的不同,如果您曾经敢在Oracle中使用区分大小写的表/列名,那就不好笑了

    至于约束,我更喜欢在“createtable”之后的单独语句中添加它们。如果在Oracle中使用char(1)和check约束实现布尔数据类型,而PostgreSql直接支持此数据类型,则约束集可能会有所不同

    至于“标准”:一个例子

    SQL99 standard: for SELECT DISTINCT, ORDER BY expressions must appear in select list
    
    这条消息来自PostgreSql,Oracle 11g没有抱怨。14年后,他们会改变吗

    一般来说,您仍然需要编写特定于数据库的代码

    至于您的结论:在我们的场景中,我们使用模型驱动的方法实现了一个可移植的数据库应用程序。这个逻辑元数据由应用程序使用,不同的数据库类型有不同的后端。我们不使用任何ORM,只使用“直接SQL”,因为这简化了SQL语句的调优,并提供了对所有SQL特性的完全访问。我们编写了自己的图书馆,后来我们发现关键思想与“Anorm”的这些思想相匹配

    好消息是,虽然有很多小麻烦,但它工作得相当好,即使是复杂的查询。例如,窗口聚合函数是非常可移植的(row_number(),partition by)。您必须在Oracle上使用listagg,而在PostgreSql上则需要string_agg。在PostgreSql中,递归Commo表表达式需要“with Recursive”,Oracle不喜欢它。PostgreSql支持查询中的“限制”和“偏移”,您需要在Oracle中包装这一点。如果在Oracle和PostgreSql中都使用SQL数组(数组作为表中的列),这会让你发疯。Oracle上有物化视图,但在PostgreSql中不存在。令人惊讶的是,不仅可以用Java编写数据库存储过程,还可以用Scala编写数据库存储过程,这在Oracle和PostgreSql中都非常有效。这个列表不完整。但到目前为止,我们设法为任何“可移植性问题”找到了一个可接受的(=快速)解决方案

    有回报吗?在我们的场景中,有一个中央Oracle安装(RAC,读/写),但每个应用服务器上都有作为本地主机数据库的分布式PostgreSql安装(只读)。这将大大提高性能和可扩展性,而不会降低成本

    如果您真的只想在数据库中解决这个问题,那么有一种可能性:将任何内容放在存储过程中,用Java/Scala编写这些过程,并限制自己在应用程序中调用这些过程和读取结果集。这当然只是将复杂性从应用程序层转移到数据库中,但您接受了黑客攻击:-)

    如果使用Java存储过程,触发器是相当标准化的。如果您的数据库、管理层和da支持它