我是 PostgreSQL 的新手,一般来说对数据库有点陌生。我们应该如何在 Postgres 中索引UUID值,是否有既定的方法?我分为使用散列和使用特里树,除非已经有内置的东西可以自动使用。无论我使用什么,都将处理大量数据。
SP-GiST 运算符族“text_ops”使用树索引。因为 UUID 很长而且非常不同,所以即使我只会进行完整匹配搜索,这些听起来也很吸引人。
还有一个哈希选项。散列是 O(1),当然除了相等我不需要做任何比较,但是因为 UUID 很长,我担心从它们生成散列会浪费很多时间。
或者这是否过于依赖系统和使用细节?
在大多数情况下,我宁愿使用bigserial,但有人告诉我为此使用uuid。我们需要uuid,因为我们可能有多个服务器使用不同的数据库,因此不能保证我们将拥有唯一的 bigint。我们可以为每个服务器使用不同的序列(和种子),但它仍然不如 UUID 灵活。例如,如果不转换 ID 及其引用,我们将无法将数据库条目从一台服务器迁移到另一台服务器。
我一直在 AdventureWorks2012 数据库中挖掘并看到在几个表中使用的 Row_GUID。
我的问题有两个部分:
何时应该包含 Row_GUID 列?
Row_GUID 列的用途和好处是什么?
我最近继承了一个使用BINARY(16)而不是UNIQUEIDENTIFIER存储 Guid的 SQL Server 数据库。它对包括主键在内的所有内容都执行此操作。
我应该担心吗?
我正在研究一种广泛使用UUIDs for PRIMARY KEYs 的数据库设计。然而,这让我面临一个非常重要的选择。我如何命名这些列?我会称它们uuid为 ,但UUID作为标识符,我必须在各处引用字段名称:
CREATE TABLE thingie (
"uuid" UUID PRIMARY KEY DEFAULT public.gen_random.uuid(),
foo VARCHAR,
bar VARCHAR,
);
Run Code Online (Sandbox Code Playgroud)
一个直接的替代方案似乎是调用这些列id:
CREATE TABLE thingie (
id UUID PRIMARY KEY DEFAULT public.gen_random.uuid(),
foo VARCHAR,
bar VARCHAR,
);
Run Code Online (Sandbox Code Playgroud)
这样,我就没有列名,并且从语义上讲,我可以说 UUID 确实是一种 ID;在维恩图中,UUID 圆将完全放置在 ID 圆中。
然而,我(并且我相信许多其他人)已经习惯于id与自动递增INTEGER列关联,以至于我担心通过调用这些 ID 来打破某种不成文的规则id。
如果您能通过一些可靠的自行车脱落来消除我的困惑,我将非常感激。事实上,我的问题是:你会如何称呼你的-typed 代理键,为什么?UUID
我的一位同事给我发了一个有趣的问题,我无法完全解释。
他运行了一些代码(包括在下面)并从中得到了一些意想不到的结果。
本质上,当将 a UniqueIdentifier(Guid从这里开始我将称之为)转换为 a binary(or varbinary) 类型时,结果的前半部分的顺序是倒序的,但后半部分不是。
我的第一个想法是系统的字节序是原因,并且Guid保留了显示,但binary不能保证形式。
显然这是一个实现细节,但我想知道是否有一个很好的解释。
代码:
declare @guid uniqueidentifier = '8A737954-CBEC-40CE-A534-2AFFB5A0E207';
declare @binary binary(16) = (select convert(binary(16), @guid));
select @guid as [GUID], @binary as [Binary];
Run Code Online (Sandbox Code Playgroud)
结果:
GUID Binary
8A737954-CBEC-40CE-A534-2AFFB5A0E207 0x5479738AECCBCE40A5342AFFB5A0E207
Run Code Online (Sandbox Code Playgroud)
如您所见,每个部分的前半部分Guid(一直到40CE)是向后存储的。也就是说,the的第一部分是向后的,然后是第二部分,然后是第三部分,但是这些部分的顺序是保留的。之后,最后两个部分按照它们在.GuidGuid
谁能解释一下?(下面包含一个更大的测试集。)
代码:
declare @guid_to_binary table
(
[id] int identity(1,1),
[guid] uniqueidentifier,
[binary_conversion] binary(16)
);
declare @i int = 1;
while @i <= 100
begin
insert into …Run Code Online (Sandbox Code Playgroud) SELECT gen_random_uuid()
产生输出
ERROR: function gen_random_uuid() does not exist
SQL state: 42883
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
Run Code Online (Sandbox Code Playgroud)
我CREATE EXTENSION pgcrypto;在选定的数据库上运行并SELECT gen_random_bytes(1)完美运行(gen_random_bytes不适用于pgcrypto未手动创建扩展的其他数据库)。
% psql --version
psql (PostgreSQL) 9.5.3
Run Code Online (Sandbox Code Playgroud)
Ubuntu 版本是 16.04。
Microsoft SQL Server 提供了NEWID生成新 GUID(UUID的 Microsoft 版本)值的命令,该值可用作主键值(在其uniqueidentifier数据类型中)。这些本质上不是顺序的,因此更新索引可能效率低下。
或者,MS SQL Server 提供该NEWSEQUENTIALID命令。引用他们的文档:
创建一个 GUID,该 GUID 大于自 Windows 启动以来此函数在指定计算机上先前生成的任何 GUID。重新启动 Windows 后,GUID 可以从较低的范围再次启动,但仍然是全局唯一的。当 GUID 列用作行标识符时,使用 NEWSEQUENTIALID 比使用 NEWID 函数更快。这是因为 NEWID 函数会导致随机活动并使用较少的缓存数据页。使用 NEWSEQUENTIALID 还有助于完全填充数据和索引页。
有没有办法在 Postgres 中获得更有效索引的 UUID?
我有一个其他人创建的数据库表,它的 PK 是“uuid”类型的单列。我正在努力按该列执行简单的选择。我尝试过但没有成功的例子:
select from site where id = "9d4da323-4c20-360f-bd9b-ec54feec54f0"
select from site where id = UUID('9d4da323-4c20-360f-bd9b-ec54feec54f0')
select from site where id::text = '9d4da323-4c20-360f-bd9b-ec54feec54f0'
正确的语法是什么?