设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 数据 创业者 手机
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

sql – 如何保持数据不排序?

发布时间:2021-02-03 22:03 所属栏目:116 来源:网络整理
导读:我有一个表A: Col1 Col212 a12 c12 b 如果我编码:从A中选择*; 结果是: Col1 Col212 a12 b12 d 我想获取数据是: Col1 Col212 a12 c12 b 如何获取数据不排序? 解决方法 要理解的关键是SQL表没有排序.在没有ORDER BY的情况下SELECT时看到的行的顺序保持不变

我有一个表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”.

(编辑:ASP站长网)

    网友评论
    推荐文章
      热点阅读