微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

sqlite 文本作为主键 vs 自动增量整数

如何解决sqlite 文本作为主键 vs 自动增量整数

我目前正在讨论使用 text 列作为键的两种策略。

一个是简单地使用 text 列本身作为键,如下所示:

create table a(
    key_a text primary key,)

create table b(
    key_b text primary key,)

create table c(
    key_a text,key_b text,foreign key("key_a") references a("key_a"),foreign key("key_b") references b("key_b")
)

我担心这会导致每个键都被复制,一次在 ab 中,另一个c 中,因为 text 不是内联存储的.

我的第二种方法是在前两个表上使用 autoincrement id 作为主键,并在表 c 上使用这些 id 来引用它们,如下所示:

create table a(
    id_a integer,key_a text unique,primary key("id_a" autoincrement)
)

create table b(
    id_b integer,key_b text unique,primary key("id_a" autoincrement)
)

create table c(
    id_a integer,id_b integer,foreign key("id_a") references a("id_a"),foreign key("id_b") references b("id_b")
)

在第一种情况下,我是否应该担心文本重复?或者,sqlite 是否以某种方式实习这些并且只是为两者使用一个 id,类似于第二个策略的作用?

解决方法

SQLite 不会自动压缩文本。所以你的问题的答案是“不”。

您应该使用文本还是自动递增的 id 作为主键?这可能是一个复杂的问题。但令人高兴的是,答案是它没有太大区别。也就是说,有一些注意事项:

  • 整数是固定长度的。一般来说,在 B 树索引中,固定长度的键比可变长度的键更有效。
  • 如果字符串很短(例如 1 或 2 或 3 个字符),那么它们可能比整数更短(或不长)。
  • 如果您更改字符串(例如,如果它最初拼写错误),则使用“人工”主键可以使这变得简单:只需更改一个表中的值。使用字符串本身作为键可能会导致对大量表进行大量更新。
,

在第一种情况下,我是否应该担心文本重复? 或者sqlite是否以某种方式实习这些并且只是为两者使用一个id,类似 第二种策略的作用是什么?

是的,您的担心是正确的。文本将被复制。

此外,即使您没有在第一种方法中定义整数主键,也有一个。

来自Rowid Tables

rowid 表的 PRIMARY KEY(如果有的话)通常不是 表的真正主键,因为它不是唯一的 底层 B 树存储引擎使用的键。的例外 此规则是当 rowid 表声明一个 INTEGER PRIMARY KEY 时。在 例外,INTEGER PRIMARY KEY 成为 rowid 的别名。

rowid 表的真正主键(用作 在底层 B 树存储引擎中查找行的关键)是 rowid

在您的第二种方法中,实际上您没有通过定义整数主键在每个表 ab 中创建新列。
您正在做的是为现有的 rowid 列设置别名:

  • id_a 成为表 rowid
  • a 的别名
  • id_b 成为表 rowidb 的别名。

因此,就父表中的空间而言,定义这些整数主键并不昂贵。

尽管通过使用 ON UPDATE CASCADE 定义外键来更新父表中的值时,使用第一种方法可以避免子表中的显式更新,但我建议使用第二种方法。

一个由系统分配给它的整数主键,你甚至不必知道或担心这是常见的做法。
当您想从父表中获取文本值时,您只需在创建的查询中使用该主键及其相应的外键即可访问父表。

,

为了性能(这也是一个很好的数据库实践),你应该坚持主键的数字/整数值。

至于第二种方法,我不明白您所追求的概念。你能详细说明一下吗?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。