如何通过UUID在PostgreSQL中进行排序?

时间:2017-04-05 18:24:44

标签: postgresql sql-order-by uuid postgresql-9.4

在postgresql上使用uuid_generate_v1()是否有任何订购保证?

如果是,那么保证是每台机器还是在哪台机器上生成UUID无关紧要?由于V1 UUID是按时间戳+ MAC地址,因此Postgres内部按时间戳部分排序,然后按MAC排序吗?

我可以“订购”UUID类型列并期望它始终有效(似乎有用)吗?

我想在多台机器上生成UUID(使用postgresql uuid_generate_v1()),将它们复制到一个Postgres实例,然后按UUID列排序。它必须保证按机器排序,而不是所有机器的UUID顺序。

2 个答案:

答案 0 :(得分:1)

尽管决不是绝对的答案-即此SQL(对于SQL Server)“是否在所有PostgreSQL安装中定义了行为?”,以检查GUID中每个字节的顺序。可能需要对PostgreSQL进行一些调整。

生成这样的映射应该使人们能够查看某个特定的UUID结构(定义明确的类型之一还是其​​他)在PostgreSQL中是否“以特定方式排序”。

With UIDs As (--                           0 1 2 3  4 5  6 7  8 9  A B C D E F
            Select ID = 'F', UID = cast ('00000000-0000-0000-0000-000000000011' as uniqueidentifier)
    Union   Select ID = 'E', UID = cast ('00000000-0000-0000-0000-000000001100' as uniqueidentifier)
    Union   Select ID = 'D', UID = cast ('00000000-0000-0000-0000-000000110000' as uniqueidentifier)
    Union   Select ID = 'C', UID = cast ('00000000-0000-0000-0000-000011000000' as uniqueidentifier)
    Union   Select ID = 'B', UID = cast ('00000000-0000-0000-0000-001100000000' as uniqueidentifier)
    Union   Select ID = 'A', UID = cast ('00000000-0000-0000-0000-110000000000' as uniqueidentifier)
    Union   Select ID = '9', UID = cast ('00000000-0000-0000-0011-000000000000' as uniqueidentifier)
    Union   Select ID = '8', UID = cast ('00000000-0000-0000-1100-000000000000' as uniqueidentifier)
    Union   Select ID = '7', UID = cast ('00000000-0000-0011-0000-000000000000' as uniqueidentifier)
    Union   Select ID = '6', UID = cast ('00000000-0000-1100-0000-000000000000' as uniqueidentifier)
    Union   Select ID = '5', UID = cast ('00000000-0011-0000-0000-000000000000' as uniqueidentifier)
    Union   Select ID = '4', UID = cast ('00000000-1100-0000-0000-000000000000' as uniqueidentifier)
    Union   Select ID = '3', UID = cast ('00000011-0000-0000-0000-000000000000' as uniqueidentifier)
    Union   Select ID = '2', UID = cast ('00001100-0000-0000-0000-000000000000' as uniqueidentifier)
    Union   Select ID = '1', UID = cast ('00110000-0000-0000-0000-000000000000' as uniqueidentifier)
    Union   Select ID = '0', UID = cast ('11000000-0000-0000-0000-000000000000' as uniqueidentifier)
)
Select * From UIDs Order By UID desc

在SQL Server(2014,and matches that in SQL Server 2005)中,降序顺序为:

Position by highest-to-lowest value:

A B C D E F | 8 9 | 7 6 | 5 4 | 3 2 1 0

由于SQL Server的newsequentialid利用此顺序生成了易于索引的GUID ,因此行为可能永远不会改变。 SQL Server还必须在所有系统上维护此行为以支持复制。因此,如果问题是关于SQL Server的,那么我肯定会说“在SQL Server中的中存在GUID的一致顺序”,这绝对可以依赖于SQL Server中的。 / p>

但是,此顺序与.NET的GUID顺序不同,如果PostgreSQL中的顺序不同,我也不会感到惊讶。 SQL Server中“翻转”的差异是因为它遵循COM GUIDs的“变体2”(又称Little-endian)排序;即使对于“变体1” UUID也是如此。 (但是,为什么这些组本身从右到左排序:更多的Microsoft历史记录?)

有趣的问题仍然存在:在哪里/如何指定了 PostgreSQL中订购的 ?如果规范不明确,是否仍可以将实现视为行为公理?

see this question for more details about SQL Server's UUIDs;以及为什么存在这些差异的美味细节。

答案 1 :(得分:0)

UUID不是为了订购而设计的。

如果要根据创建顺序选择记录,则应使用时间戳date_creationauto-increment列(不适用于您的特定情况),或使用算法保证创建您自己的ID排序;例如,连接时间戳+ UUID,或时间戳+自动增量。

您可以在数据库中为后面的选项创建function