相关疑难解决方法(0)

Postgres 中 UUID 列的默认值

Postgres 9.x 中,对于类型为 的列UUID,如何指定要自动生成的 UUID 作为任何行插入的默认值?

postgresql default-value uuid

96
推荐指数
3
解决办法
15万
查看次数

使用大 IN 优化 Postgres 查询

此查询获取您关注的人创建的帖子列表。您可以关注无限数量的人,但大多数人关注 < 1000 人。

使用这种查询方式,明显的优化是缓存"Post"id,但不幸的是我现在没有时间这样做。

EXPLAIN ANALYZE SELECT
    "Post"."id",
    "Post"."actionId",
    "Post"."commentCount",
    ...
FROM
    "Posts" AS "Post"
INNER JOIN "Users" AS "user" ON "Post"."userId" = "user"."id"
LEFT OUTER JOIN "ActivityLogs" AS "activityLog" ON "Post"."activityLogId" = "activityLog"."id"
LEFT OUTER JOIN "WeightLogs" AS "weightLog" ON "Post"."weightLogId" = "weightLog"."id"
LEFT OUTER JOIN "Workouts" AS "workout" ON "Post"."workoutId" = "workout"."id"
LEFT OUTER JOIN "WorkoutLogs" AS "workoutLog" ON "Post"."workoutLogId" = "workoutLog"."id"
LEFT OUTER JOIN "Workouts" AS "workoutLog.workout" ON "workoutLog"."workoutId" = "workoutLog.workout"."id"
WHERE
"Post"."userId" IN …
Run Code Online (Sandbox Code Playgroud)

postgresql performance index optimization postgresql-performance

51
推荐指数
2
解决办法
7万
查看次数

当所有值都是 36 个字符时,使用 char 和 varchar 进行索引查找会明显更快吗

我有一个旧模式(免责声明!),它使用基于哈希生成的 id 作为所有表的主键(有很多)。这种 id 的一个例子是:

922475bb-ad93-43ee-9487-d2671b886479
Run Code Online (Sandbox Code Playgroud)

改变这种方法是不可能的,但是索引访问的性能很差。撇开这可能的无数原因不谈,我注意到有一件事似乎不太理想 - 尽管所有许多表中的所有 id 值的长度都正好是 36 个字符,但列类型是varchar(36)而不是 char(36)

将列类型更改为固定长度是否会char(36)提供任何显着的索引性能优势,除了每个索引页的条目数量增加很小等之外?

即在处理固定长度类型时 postgres 的执行速度是否比处理可变长度类型快得多?

请不要提及微小的存储节省 - 与对列进行更改所需的手术相比,这无关紧要。

postgresql performance index varchar

38
推荐指数
1
解决办法
1万
查看次数

什么是最有效的 UUID 列类型

为了存储 128 位 UUID,有多种存储选项:

  1. 一个字节[16]列
  2. 两个 bigint/long(64 位)列
  3. CHAR(36) 列 - 32 个十六进制数字 + 4 个破折号。
  4. 一个 UUID 数据库特定列,如果 db 支持它

从索引的角度来看,哪些是最有效的?如果数据库不支持专用的 uuid 类型,那么 1、2、3 中的哪一个是最佳选择?

mysql postgresql index oracle sql-server

19
推荐指数
1
解决办法
2万
查看次数

如何以扩展的树状方式对递归查询的结果进行排序?

假设您有这样的nodes表:

CREATE TABLE nodes
(
    node serial PRIMARY KEY,
    parent integer NULL REFERENCES nodes(node),
    ts timestamp NOT NULL DEFAULT now()
);
Run Code Online (Sandbox Code Playgroud)

它代表了一个标准的类似节点的树结构,根节点在顶部,几个子节点悬挂在根节点或其他子节点上。

让我们插入几个示例值:

INSERT INTO nodes (parent)
VALUES (NULL), (NULL), (NULL), (NULL), (1), (1), (1), (1), (6), (1)
     , (6), (9), (6), (6), (3), (3), (3), (15);
Run Code Online (Sandbox Code Playgroud)

现在我想检索前 10 个根节点及其所有子节点,深度为 4:

WITH RECURSIVE node_rec AS
(
    (SELECT 1 AS depth, * FROM nodes WHERE parent IS NULL LIMIT 10)

    UNION ALL

    SELECT depth + 1, n.*
    FROM nodes …
Run Code Online (Sandbox Code Playgroud)

postgresql cte order-by recursive

14
推荐指数
1
解决办法
1万
查看次数

为什么我的 UNIQUE 约束没有触发?

我有这个UNIQUE限制:

ALTER TABLE table ADD CONSTRAINT "abc123" UNIQUE
("col1", "col2", "col3", "col4", "col5", "col6", "col7", "col8");
Run Code Online (Sandbox Code Playgroud)

然后我这样做:

INSERT INTO table ("col1", "col2", "col3", "col4", "col5", "col6", "col7", "col8") 
VALUES ('a', 'b', 'c', 'd', 'e', 'f', null, true);
INSERT INTO table ("col1", "col2", "col3", "col4", "col5", "col6", "col7", "col8") 
VALUES ('a', 'b', 'c', 'd', 'e', 'f', null, true);
Run Code Online (Sandbox Code Playgroud)

两者都有效。两行已添加到表中。从逻辑上讲,第二个应该失败。但事实并非如此。

我究竟做错了什么?这让我发疯。

注意:如果这是我自己的数据,我将拥有一个真正独特的列,而不是这个“疯狂”的UNIQUE约束。问题是这个表保存了我的银行帐户的记录,而且他们愚蠢地在 CSV 转储中没有真正的“唯一”列,我可以用它来实际确保不插入重复的行,所以我有提出一个组合整个表中所有列以确定唯一性的方法。

postgresql null unique-constraint

14
推荐指数
2
解决办法
9798
查看次数

索引大文本的最佳散列技术

幸运的是当我尝试在大长度文本列上创建唯一索引时,Erwin Brandstetter救了我

插入率的上限是每年数百亿行。

对于我的实现,散列永远不需要离开数据库,但散列数据必须经常与外部数据进行比较才能存在。

根据我针对这些目的进行优化的有限经验,我假设散列的最佳数据类型是bytea. 替代方案当然是更长的十六进制字符串。

bytea这些哈希的最佳数据类型是否正确?

如果bytea不是最优的,什么是最优的?

我的意图应该如何实现?

澄清

我根据 Erwin Brandstetter 的建议使用文本的哈希值,以确保大文本是唯一的。我有限的理解是,原始二进制数据总是性能最好的,尤其是与字符串相比时。

只需比较哈希是否存在即可抢占唯一性违规,因此哈希很高兴永远不需要离开数据库。由于 libpqxx 令人难以置信的设计,看起来好像数据可以简单地通过准备好的语句输入并使用(decode(md5($1::text), 'hex')). 当我更熟悉bytea通过 libpqxx 3.1 插入时,我会将其移至 C++。

对于此实现,冲突是可以接受的,因为可以在不破坏系统的情况下重建数据以符合要求。

如果愉快地达到最大吞吐量,那么应该预期经济资源将可用于容纳它;因此,主要关注点始终是性能,所以如果我对 Postgres 的功能及其分区表处理这些行数的能力的理解是准确的,那么它有望在很长一段时间内成为该工作的正确工具。幸运的是,超过几秒钟的数据永远不会改变,我的理解是 Postgres 分区表可以将这些数据制成碎肉。如果没有,这将是那些好问题之一。

postgresql index optimization bytea

7
推荐指数
1
解决办法
2121
查看次数

带有嵌套 CTE 的条件插入?

我想弄清楚是否有一种方法可以使嵌套 CTE 适用于这种特殊情况。

考虑以下基于实际应用程序的(高度人为设计的)场景:有一个员工 ID 的单列表。然后是包含所有详细信息的员工属性表。(单列表背后的主要原因通常是理所当然地需要在知道实际员工的任何详细信息之前批量创建和分配新员工 ID。)

现在到手头的任务,我们要为新员工插入详细信息(即姓名),但首先我们需要检查是否已经存在具有该姓名的员工。如果是,我们将简单地返回 id,如果不是,我们将创建一个新的员工记录,然后插入详细信息,最后返回新创建的 id。

要重新创建此测试场景:

CREATE TABLE public.employee (
    id text DEFAULT gen_random_uuid(),
    PRIMARY KEY (id)
);

CREATE TABLE public.employee_details (
    employee_id text,
    name text,
    PRIMARY KEY (employee_id),
    FOREIGN KEY (employee_id) REFERENCES public.employee(id)
);
Run Code Online (Sandbox Code Playgroud)

我试图敲定的查询如下所示。

with 
e as 
    (select name, employee_id from employee_details where name = 'jack bauer'), 

i as (insert into employee_details (name, employee_id) 
    select 'jack bauer', 
        (with a as (insert into employee values(default) RETURNING id) select a.id from a)
    where not exists …
Run Code Online (Sandbox Code Playgroud)

postgresql insert cte postgresql-10

6
推荐指数
1
解决办法
2680
查看次数

UUID 或 BIGSERIAL 外键 Postgres

我有 8 个使用 UUID 主键的表,其中 7 个使用 UUID 外键。使用 BIGSERIAL 而不是 UUID 对性能会更好吗?

postgresql primary-key uuid

4
推荐指数
1
解决办法
2001
查看次数

SHA3​​-256 哈希的索引、数据类型配置和 DBMS 的定义

我正在设计一个系统,在该系统中我需要能够使用文件或字符串 SHA3-256 哈希来搜索数据库。

例如,测试的哈希是

36f028580bb02cc8272a9a020f4200e346e276ae664e45ee80745574e2f5ab80
Run Code Online (Sandbox Code Playgroud)
  1. 我应该设置哪个DATATYPE来存储这个值?我听说过使用 BINARY 而不是 VARCHAR。
  2. 我应该如何索引此列,以便按哈希搜索最快?
  3. 我应该使用哪种数据库管理系统(如 PostgreSQL、DB2、SQL Server)或文档软件(如 MongoDB)最有效地允许我通过哈希存储和检索记录?我只有像 MySQL 这样的关系数据库管理系统的经验,但也许像 MongoDB 这样的文档存储会是更好的方法。

index database-design datatypes hashing

3
推荐指数
1
解决办法
136
查看次数