【问题标题】:Does SQLite's VACUUM preserve key relations?SQLite 的 VACUUM 是否保留关键关系?
【发布时间】:2023-03-12 18:55:01
【问题描述】:

PRAGMA foreign_keys 已启用。

foo 没有明确的INTEGER PRIMARY KEY

barfoo_rowid INTEGERFOREIGN KEY (foo_rowid) REFERENCES foo(rowid)

foo 中的 f 行有一个 xrowidbar 中的 b 行有一个 foo_rowid x.

如果 VACUUMfrowid 更改为 y,是否会更改 bfoo_rowidy

VACUUM 命令可以更改任何没有显式 INTEGER PRIMARY KEY 的表中条目的 ROWID。

【问题讨论】:

    标签: database sqlite foreign-keys rdbms


    【解决方案1】:

    不,它不适用于非主键 rowid。让我们创建没有主键的表:

    $ sqlite3 test.db
    SQLite version 3.7.16.2 2013-04-12 11:52:43
    sqlite> create table test(name varchar(20));
    sqlite> insert into test values('a'),('b'),('c');
    sqlite> select rowid,* from test;
    1|a
    2|b
    3|c
    

    到目前为止一切顺利。让我们删除一些东西:

    sqlite> delete from test where rowid=2;
    sqlite> select rowid,* from test;
    1|a
    3|c
    

    哇,rowid 被保留了——这很有希望!但是,VACUUM 之后会发生什么?

    sqlite> vacuum full;
    sqlite> select rowid,* from test;
    1|a
    2|c
    sqlite>
    

    糟糕,它被重新编号了!

    换句话说,您必须创建真正的自动增量列才能使其正常工作并在 VACUUM 之后保持您的 ID 不变。

    【讨论】:

    • 这个答案只说明VACUUM可以改rowids;我的问题是:如果发生这种情况,它会改变外键来匹配吗?
    • 这是否意味着如果我创建一个非自动增量主键整数列,那么在vacuum 操作之后该列中的值仍然可以更改?跨度>
    • 不,任何物理列(您定义为 CREATE TABLE 语句的一部分)都不能通过真空更改。
    【解决方案2】:

    这是不可能的,因为a rowid cannot be referenced by another table。如果列可以被外键引用,则不能被VACUUM更改。

    【讨论】:

    • 您确实可以在外键约束中引用 rowid。试试看。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-10
    • 2012-01-24
    • 2020-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-25
    相关资源
    最近更新 更多