Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么表中的行在更新后发生更改?PostreSQL_Sql_Postgresql - Fatal编程技术网

为什么表中的行在更新后发生更改?PostreSQL

为什么表中的行在更新后发生更改?PostreSQL,sql,postgresql,Sql,Postgresql,我的初始表格 使用更新版本后的表 从“表”中选择*

我的初始表格

使用更新版本后的表
从“表”中选择*
在一个数学集合中,绝对没有默认的顺序,因为集合是“包”,包中的物品在旅行时会“混合”。。。(只要看看你女朋友钱包里的东西就可以说服你自己!)


这就是为什么SQL SELECT语句中有一个ORDER BY子句的原因,因为RDBMS永远无法确保任何顺序都得到遵守!并且返回行的位置可以随时更改

行顺序更改的原因是PostgreSQL实现了多版本控制

在PostgreSQL中更新行时,不会修改实际的表条目(“tuple”,用术语来说)。相反,一个新版本的行被插入到表中,旧版本被标记为无效(我在这里简化)。并发读取器仍然可以访问旧元组以获取原始数据。当没有人再需要旧元组时,它被自动真空回收


在您的例子中,新的元组被添加到表的末尾。因此,如果一个
UPDATE
似乎移动了一行,那是因为实际情况就是这样。

我自己也不是一个真正的PostgreSQL人,但一般来说,表上应用的任何主键/默认索引都将决定行的排序顺序(如果在SELECT语句中不包含任何特定的order BY)。在这种情况下,我的猜测是“version”列是这个特定表的默认排序顺序中的一个因素。至少对每个人来说,了解您所做的更新都很有用。使用
select*from“table”
更新版本并不像您想象的那样不言自明。行会发生更改,因为更新会更改某些行的内容。你的确切意思是什么?我相信OP提出的具体问题是,“为什么在更新ID=3的行的版本号后,行的显示顺序(执行简单的SELECT*FROM表)发生了变化?”@craig。默认情况下,行是无序的,主键/索引不会进入其中。如果你想要一个
订单
,你需要用一个
orderby
来指定它。很肯定,他一直在使用一个堆表。在这种情况下,由于重写,更新导致第3行移动到堆的末尾。@TarekSalha:即使Postgres确实有“堆表”(即聚集索引)以外的内容,但如果没有
的排序顺序,它仍然不能保证一定的排序顺序(想想并行执行或同步序列扫描)@一匹没有名字的马你是真的。。。即使在像Microsoft SQL Server这样的聚集索引中,也没有默认的常量排序。因为引擎是在多线程中完成的,所以一个任意线程将先完成一个线程,最后完成一个线程,很少在每次执行时都是相同的。。。因此,最终的连接结果将具有任意顺序。还有许多其他情况也会出现同样的行为。@Tarek_Salha是的,因为PostGreSQL进行更新的唯一方法是系统地创建一个新行。这种“奇怪的”PG行为是由于MVCC的糟糕实现造成的。请看我关于这些问题的论文。。。