Database DB:是否使用标识列?

Database DB:是否使用标识列?,database,design-patterns,Database,Design Patterns,在设计表时,我这里的同事说,我应该避免使用标识列,因为它特定于SQL Server和MS Access,但我不同意他的观点,因为它使我的编码更简单 我是否应该使用标识栏?如果不是,从应用程序代码创建标识列的最佳方法是什么?您不能将应用程序与数据库供应商完全分离。如果您这样做,您将无法利用数据库提供的任何功能 我要说的是使用标识栏。例如,如果您转到Oracle,则可以使用序列。没什么大变化 我不知道您使用的是什么技术,但有一件事会有所帮助,那就是使用诸如Hibernate或iBATIS之类的工具(

在设计表时,我这里的同事说,我应该避免使用标识列,因为它特定于SQL Server和MS Access,但我不同意他的观点,因为它使我的编码更简单


我是否应该使用标识栏?如果不是,从应用程序代码创建标识列的最佳方法是什么?

您不能将应用程序与数据库供应商完全分离。如果您这样做,您将无法利用数据库提供的任何功能

我要说的是使用标识栏。例如,如果您转到Oracle,则可以使用序列。没什么大变化


我不知道您使用的是什么技术,但有一件事会有所帮助,那就是使用诸如Hibernate或iBATIS之类的工具(我认为它们都适用于Java和.NET),这会将您与数据库实现细节区分开来。然后,若您更改了数据库供应商,则无需更改应用程序代码,只需更改配置即可。(至少在理论上!)

据我所知,每一个稍微严肃的RDBMS都有某种独特的表编号方案

  • Access和SQL Server具有标识列
  • MySQL具有自动增量列
  • PostgreSQL具有序列
  • sqlite有一个隐式的ROWID列
  • 甲骨文有某种序列,尽管我一点都不熟悉
  • 我主要使用它,理论上它并不总是一个要求,但如果你想保持引用完整性,int比varchar更难存储和比较,特别是如果你的外键比单个列更复杂的话。

    使用Identity column

    它确实将“应用程序逻辑”与“业务逻辑”分开


    假设您使用“电子邮件”作为主键(从“业务逻辑”的角度来看,这是有意义的)。当该电子邮件不再存在且您的用户想要编辑您的电子邮件时,您将遇到麻烦。

    除非您完全了解其缺陷,并且没有使用序列或模拟序列生成器的有效理由,否则不要使用identity列

    序列更加灵活,没有标识列的缺点/限制

    发件人:

    自动递增的痛苦

    复制数据时 保恒等值

    自动递增的关键点可以成为 当你需要复制整本书时会感到痛苦 选项卡并保留主键 价值试图直接插入到 标识列将导致 正在引发的错误。典型的 供应商提供了一些声明 允许您临时删除 约束,以便可以插入现有的 价值观在MSSQL中,您可以发布 命令

    “设置标识并插入产品”

    其他供应商将要求您放弃 单击该约束,然后重新启用它

    更痛苦-如何检索 新插入的行

    此外,服务器通常 提供不同的检索方法 新创建的项目的标识列值 插入的行。对于MySQL,这是 最后一个\u INSERT\u ID()函数和 MSSQL它是@@identity例如select @@身份

    MS SQL Server 2011将支持顺序

    如果使用不支持序列的RDBMS服务器(如MSSQL pre-2011或MySQL),则有两种选择:

  • 切换到。这确实是最简单的选择。您可以获得企业级、完全开源的RDBMS服务器。如果你愿意,你也可以得到商业支持
  • 使用支持模拟序列的数据访问库。实现,例如,make。这与上述情况并不相互排斥。使用JPA2.0和PostgreSQL将使您的生活比使用MySQL的原始JDBC轻松得多

  • 你不熟悉Oracle中的定序器,所以你决定“每个稍微严肃的RDBMS在每个表中都有一个数字方案”@Dave,42总是一个数字,但数字并不总是42。是的,不知道你的意思。上次我检查Oracle是否有生成器,很像PostgreSQL的序列,它们不是按表生成的。@Dave,它说明了一条语句在脱离上下文时并不等同于原始含义。类似于你在第一次评论中对我的帖子所做的。然而,在这个问题上;如果任何类型的行号在整个数据库中都是唯一的,那么它怎么可能在单个表中不唯一呢?在证明错误之前,我将坚持我的断言,即Oracle是一个严肃的RDBMS。我可能没有在我的帖子中使用Oracles术语,这就是我添加免责声明的原因。我并不是说Oracle不是一个严肃的RDBMS。我只想指出,您的断言“每个稍微严重的RDBMS都有某种独特的每个表的编号方案”是错误的,因为在Oracle、PostgreSQL以及Interbase/Firebird的情况下,它不是“每个表”。我们还必须处理这类概念上的差异,而不是简单地认为每个RDBMS都是某种“标识列”。我认为,如果您添加一个名为“identity”的新表,并在其中存储每个表的最新ID,那么每次需要表的新ID时,都可以非常简单地说SET[tablename]+1。