【问题标题】:Why do we use primary key auto increment, and not just auto_increment?为什么我们使用主键自动增量,而不仅仅是 auto_increment?
【发布时间】:2021-07-04 15:58:57
【问题描述】:

我想知道为什么我们在 sql 中使用 PRIMARY_KEY_AUTO_INCREMENT 而不仅仅是 AUTO_INCREMENT 作为表中的 id。如果我们只是将id的数据类型设置为AUTO_INCREMENT,是不是会自动递增,从而每次生成一个unique id?因此,在顶部设置PRIMARY_KEY(唯一标识表中的每个项目)有什么意义?

谢谢!!

【问题讨论】:

  • 您使用的是哪个 dbms?这是产品特定的功能。
  • 他们做不同的事情。 auto_increment 定义如何计算列的默认值。 primary key 指定该列唯一标识每一行,而不是NULL。一些支持auto_increment 的数据库坚持将该列用作主键。这是有道理的,但声明做了不同的事情。
  • 你的意思是primary key auto_increment
  • @GordonLinoff 感谢您的洞察力。那么auto-increment 是否会增加每一列的值,而不是每一行——因此只给每一列一个唯一的值?谢谢!
  • @jarlh 我正在使用我认为用 SQLite 实现的 android-studio

标签: sql sqlite primary-key auto-increment


【解决方案1】:

因为constraints,因为SQL 是declarative language,因为它是自记录的。

AUTO_INCREMENTPRIMARY KEY 做两件截然不同的事情。

AUTO_INCREMENT 不是标准 SQL,但大多数数据库都有类似的东西。 In 通常将默认值设为递增整数。这就是主键的机制元素:自动递增的整数是一个不错的唯一 ID。

PRIMARY KEY 做了很多事情。

  1. 列是not null
  2. 列是unique
  3. (非标准,但几乎总是)列已编入​​索引。
  4. 这些列被声明为主键。
  5. 不能将其他列声明为主键。

大多数是值的约束。它必须存在 (1),它必须是唯一的 (2),并且它必须是唯一的主键 (5)。约束保证数据如您所愿。如果没有它们,您可能会不小心插入具有相同主键或没有主键的多行。或者该表可能有多个“主”键,您使用哪个?有了约束,您不必每次获取数据时都检查数据,您知道它会在声明的约束范围内。

索引主键 (3) 是一种优化。您可能会经常按主键搜索。索引不是 SQL 标准的一部分。这可能令人惊讶。它们是实现 SQL 的细节。索引不会影响查询的结果,并且 SQL 标准避免告诉数据库他们应该如何做事。这就是 SQL 如此普遍的部分原因,它是声明式的。

在声明性语言中,您不会说如何做,而是说您想要的。 SQL 查询说明您想要什么结果,数据库会为您计算出来。您可以将上述大部分实现为约束和触发器,但如果您这样做,数据库将无法理解为什么您要这样做,并且无法使用它来帮助您。通过向数据库声明“这是主键”,它可以按照它认为合适的方式处理它。数据库添加了必要的约束。数据库添加了它的优化,这可能不仅仅是索引。数据库可以在查询中使用此信息来识别唯一行。您将受益于 50 年的数据库理论。

最后,它让人们知道专栏的目的。任何人都可以阅读架构并知道该列是主键。六个月后任何人都可以成为你。

【讨论】:

  • 您好,谢谢您的回答。我在看 Gordon Linoff 的评论:“他们做不同的事情。auto_increment 定义了如何为列计算默认值。主键指定该列唯一标识每一行并且不是 NULL。一些支持 auto_increment 的数据库坚持认为该列被用作主键。这是有道理的,但声明做不同的事情。 ......我有点困惑。那么每一列的自动递增,而主键是每一行(除了你列出的所有原因)?谢谢。
  • @CodingChap 两者都用于列。它们经常一起使用,但它们做不同的事情。声明一列primary key 表示该列唯一标识每一行。声明一列auto_increment 表示当您插入行时,数据库将在该列中填充一个具有唯一值的空值。自动递增对于主键列非常有用,但它不会使列成为主键。
  • @CodingChap Auto increment 不是 SQL 标准的一部分(标准是 generated as identity确实将它作为主键,但许多数据库不支持)。自动增量的确切细节取决于数据库。 For SQLite you generally don't need it。 SQLite 会自动为你填写一个integer primary key 列。这是 SQLite 独有的。有些数据库根本没有自动增量,你必须使用sequences
  • @CodingChap 是的,仅适用于 SQLite integer primary key 就足够了。我之前链接到的SQLite Autoincrement documentation 解释说,SQLite already assigns a unique id to each row 它将使用它。
  • 知道了。谢谢!
【解决方案2】:

Tbh 我真的不知道这是否是原因,但通过创建主键,您可以创建索引。索引有助于加快查询速度。您可以手动创建它们,但它们也是在主键和外键上创建的。

【讨论】:

  • 这条语句NOT适用于所有数据库 - 例如 SQL Server DOES NOT 自动在外键....
  • 哦,好的,很高兴知道,在这种情况下很抱歉。我主要使用 postgre
【解决方案3】:

这是 DBMS 特定的问题。让我们试着找出一些共同的优缺点。

实际上,我认为定义主键或使任何列自动递增之间没有任何相似之处。

主键不必是增量的而是唯一的。

如果您只是将一列用作自动增量,那么如果您意外或故意重置自动增量起始值,则多个列可能具有相同的值。

但是,如果您将其定义为主键,则无需担心。 如果它是主键,那么您可以将其用作其他表中的外键。 在 SQL Server 中,主键会自动创建一个集群索引,该索引将定义数据在表中的物理存储顺序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多