【问题标题】:Creating a primary key in an extant sqlite table在现有的 sqlite 表中创建主键
【发布时间】:2018-05-28 20:47:37
【问题描述】:

这里是 SQL 新手。我有一个带有表的 sqlite (3.23.1) 数据库,称之为“fp”,有 109 列和 494266 条记录。该表不是使用主键创建的。我了解(根据http://www.sqlite.org/lang_altertable.html)我无法从原始表创建主键。美好的。我想创建一个新表,其中包含一个附加列 'id' 作为主键,然后保留 fp 的其余架构和数据。

我已经使用.schema fp 获取了最初用于创建表的命令,然后在必要的子句中添加了(这是正确的术语吗?):

CREATE TABLE fp_new( id INTEGER PRIMARY KEY, ... 109 more entries )

如何有效地填充此表?我想做一些简单的事情,但是适当地收到一个错误:

sqlite> INSERT INTO fp_new SELECT * FROM fp; Error: table fp_new has 110 columns but 109 values were supplied

有没有办法以编程方式执行此操作而无需专门命名我需要插入的 109 列?

我尝试创建一个仅包含 id INTEGER PRIMARY KEY 列的表,并使用递归触发器将其填充到 1 到 494266 的范围内,然后将其与原始表连接到后者的隐式 row_id 列上,但是递归限制是 1000,如果可能的话,我想这样做而不必重新编译 sqlite3。

我相信答案分散在各种 stackexchange 帖子中,但我似乎无法找到我需要的正确集合。

谢谢你, D

【问题讨论】:

  • 您是否意识到(除非您编写了 WITHOUT ROWID(没有 rowid 列的特殊/不同的表))实际上您确实有一个名为 rowid 即编码column_name INTEGER PRIMARY KEY 只是为 rowid(唯一的 64 位有符号整数)创建一个别名。所以你可以参考现有表中的rowid。请注意,这只是为了提供信息。我建议定义一个别名,它们可能更容易使用。 You might find this interesting
  • @MikeT 'rowid' 只有当它像你说的那样被别名时才用作唯一标识符,通过编码'column_name INTEGER PRIMARY KEY'。如果不是这种情况,则给定行的“rowid”可以在插入/删除行和清理时改变。我忘记了提到这一点的资源。但是没有将列声明为“INTEGER PRIMARY KEY”,“rowid”不能用作主键。
  • rowid 始终存在并且是唯一的整数标识符,除非表是使用 WITHOUT ROWID 定义的。根据 “在 SQLite 中,表行通常有一个 64 位有符号整数 ROWID,它在同一个表的所有行中是唯一的。(没有 ROWID 的表是 *the 例外.)".* rowid 可能会被真空更改这一事实并不能否定它通常是最有效的,因此通常是查询计划的选定索引。吸尘可能会否定/阻碍它的用途,而不是用作唯一的行标识符。

标签: sqlite primary-key alter


【解决方案1】:

您必须编写一个提供 110 列的查询。

这不是问题,因为* 不需要是唯一的:

INSERT INTO fp_new SELECT NULL, * FROM fp;

【讨论】:

  • 这会导致 sqlite> INSERT INTO flight SELECT NULL, * from flight_performance;错误:UNIQUE 约束失败:flights.INTEGER
  • 您没有提到任何 UNIQUE 约束(原始表没有)。
  • 原表没有这样的约束。但是使用“id INTEGER PRIMARY KEY”创建新表不会引入唯一约束吗?
猜你喜欢
  • 2016-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-26
相关资源
最近更新 更多