使用LIKE查询,外键或jsonb数组来过滤Postgres SELECT

时间:2015-12-27 04:13:38

标签: sql postgresql

我有一个表,它假设包含与其他表的关系。但我只需要这些关系进行过滤,即在这种情况下的关系不应该作为外键或某种引用 - 我只需要搜索它们。它像标签或其他东西一样工作 这是一个例子:

CREATE TABLE "public"."table_name" 
(
    "id" uuid NOT NULL DEFAULT uuid_generate_v4(),
    "relations" text NOT NULL,
    "some_column" text,
    "some_another_column" int4,
    "created" timestamp(6) WITH TIME ZONE NOT NULL DEFAULT now(),
    CONSTRAINT "table_name_pkey" PRIMARY KEY ("id") NOT DEFERRABLE INITIALLY IMMEDIATE,
    CONSTRAINT "owner" FOREIGN KEY ("owner") REFERENCES "public"."user" ("id") ON UPDATE NO ACTION ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE,
)
WITH (OIDS=FALSE);
ALTER TABLE "public"."table_name" OWNER TO "postgres";

relations列将包含多个uuid键。此列不是SELECT ed,我打算仅将其用于过滤。在这种情况下,我打算使用此类查询从仅此表中选择行:

SELECT 
    id, some_column, some_another_column 
FROM 
    table_name 
WHERE 
    relations LIKE '%c56c8a4f-765a-4e1c-9638-f3736a25da17%' 
    AND owner = 'badee659-1fca-412a-bcf6-c73ecf1e65aa';

当然,我将创建一个多列(owner,relations)索引。

这是执行此类搜索查询的好方法吗? relations列平均每行包含1到10个uuids。

或者,也许我应该创建一个额外的表,其中包含一个用于每个'关系'的uuid和用于引用table_name表的FK?在这种情况下,我将使用JOIN个查询。

或者可能有更好的方法?可能是我应该将uuids作为数组存储在jsonb对象中?或其他什么?

1 个答案:

答案 0 :(得分:1)

指数考虑

使用位置LIKE的运算符%不是sargable。它不会使用您的索引,因为优化程序不知道如何缩小relations列中的第一个字符。

设计

几乎总是将一个列中的不同值存储为带分隔符的字符串。

请记住,关系数据库是为有效执行JOIN操作而设计的。在我看来,最好将这些数据分成列中具有原子值的行。

Json考虑

如果您的列无法预测地更改,则只应考虑

jsonjsonb数据类型。通过这样说,我的意思是,只要你能够(没有太大的开销)将你的模型融入关系模型中,你应该总是去寻找它。 hstore也是如此。

在考虑使用存储动态列的机制时,您可以阅读this blog post以获取一些信息。

该帖子的一句引言:

  

如何决定何时使用json

     

如果您的数据不适合使用普通数据库,请使用json   关系建模。

以上博文的信用证转到@Craig Ringer