sql – 如何保持数据不排序?
我有一个表A:
Col1 Col2 12 a 12 c 12 b 如果我编码:从A中选择*; Col1 Col2 12 a 12 b 12 d 我想获取数据是: Col1 Col2 12 a 12 c 12 b 如何获取数据不排序? 解决方法要理解的关键是SQL表没有排序.在没有ORDER BY的情况下SELECT时看到的行的顺序保持不变,因为数据库按顺序获取它们比其他顺序更快.当您对表执行顺序扫描时,PostgreSQL将仅按此顺序返回行;如果它可以使用查询的索引,那么通常会以其他顺序获取行.您可能会发现this answer I wrote earlier提供信息. 在PostgreSQL中,对行的UPDATE可以将它们移动到表中的不同位置,从而改变它们返回的顺序.后台autovacuum进程以及VACUUM和CLUSTER等各种其他操作也可以. 所以你绝不能依赖“默认”排序.如果要为行提供某种顺序,则必须有一个可以对其进行排序的键. 如果您创建了一个没有密钥的表,现在意识到它应该有一个,您可以通过使用ctid系统列从该情况中恢复.不要依赖于此用于生产用途,它是一个系统内部列,用户只能看到紧急恢复和诊断目的.首先,查看物理磁盘排序是否实际上是您想要的顺序: SELECT row_number() OVER () AS mytable_id,* FROM mytable ORDER BY ctid; 如果是,则可以添加一个新的键列,该键预先设置为以磁盘行顺序应用的自动递增键.有两种方法可以做到这一点.最安全的是: BEGIN; LOCK TABLE mytable IN ACCESS EXCLUSIVE MODE; ALTER TABLE mytable RENAME TO mytable_old; CREATE TABLE mytable (id SERIAL PRIMARY KEY,LIKE mytable_old INCLUDING ALL); INSERT INTO mytable SELECT row_number() OVER () AS id,* FROM mytable_old ORDER BY ctid; SELECT setval('mytable_id_seq',(SELECT max(id)+1 FROM mytable)); COMMIT; 然后,一旦你确定你对结果感到满意,DROP TABLE mytable_old;.看这个演示:http://sqlfiddle.com/#!12/2cb99/2 一种快速简便但不太安全的方法是创建列并依赖PostgreSQL从头到尾重写表: ALTER TABLE mytable ADD COLUMN mytable_id SERIAL PRIMARY KEY; 绝对不能保证PostgreSQL会按顺序分配ID,但实际上它会这样做.见this SQLFiddle demo. 请注意,当您使用SEQUENCE(这是SERIAL列创建的)时,您可能会发现一些行为.当您一次插入多行时,行可能不一定按照您期望的顺序获得分配的ID,并且它们可能以与分配ID的顺序不同的顺序“显示”(变为可见)并插入此外,如果事务回滚,生成的ID将永远丢弃,因此您会在编号中出现空白.如果您希望数据库速度很快,这是非常好的,但如果您想要无间隙编号,这并不理想.如果这就是您所需要的,请搜索“postgresql gapless sequence”. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |