我的sqlite表中是否需要“订单”列,或者使用rowid是否安全?

时间:2014-11-08 12:27:15

标签: sqlite

我有一个表与几个节点的路径相关联。子节点的顺序很重要。

CREATE TABLE PathNodes ( pathId INTEGER, nodeId INTEGER )

rowid | pathId | nodeId
------+--------+-------
1     | 10     | 101
2     | 10     | 102
3     | 11     | 103
4     | 11     | 201
5     | 11     | 202
  • 我只插入一次数据,之后它不会改变。
  • 我按正确的顺序插入数据。
  • 我从不删除任何行。
  • 插入所有数据后,我运行VACUUM

如果我想以正确的顺序获取路径的节点是否足够安全,只能按rowid排序?

SELECT * 
FROM PathNodes
WHERE pathId = 2952178
ORDER BY rowId

或者我是否需要添加明确的nodeOrder列?

1 个答案:

答案 0 :(得分:1)

在SQLite中,rowid为equivalent to an integer primary key

  

在SQLite中,类型为INTEGER PRIMARY KEY的列是其中的别名   ROWID(除非在WITHOUT ROWID表中),它总是64位签名   整数。

在您的应用程序中,数据库有助于防止重用行ID号。 SQLite might reuse rowids你现在正在使用它的方式。

  

如果您删除了行。 。 。然后从先前删除的行ROWID   可能在创建新行时重用。 。 。

由于integer primary key只是rowid的别名,而且来自已删除行的autoincrement prevents the reuse of rowids,因此在将新列声明为integer primary key autoincrement时没有空间或性能损失。并且有明显的优势。

创建一个新列integer primary key autoincrement


由于SQLite不支持直接添加声明为primary key的列,因此需要

  • 创建一个新表
  • 以正确的顺序将数据复制到其中,
  • 放下旧桌子,
  • 重命名新表。

    sqlite> create table new (
       ...> node_order integer primary key autoincrement,
       ...> pathId integer not null,
       ...> nodeId integer not null
       ...> );
    sqlite> insert into new
       ...> (pathId, nodeId)
       ...> select pathId, nodeId 
       ...> from PathNodes
       ...> order by rowid;
    

检查新数据。确保它正是你想要的。然后删除旧表,并重命名新表。

sqlite> drop table PathNodes;
sqlite> alter table new rename to PathNodes;