一对多关系的查找表

Phi*_*ord 6 postgresql database-design clustered-index referential-integrity index-tuning

我有一个ticketsid,我需要将它关联到一个查找表,其中该数据的对应项是另一个id受外部源控制的表。

tickets
- id
- sutff

lookup
- outside_data_id
- ticket_id
Run Code Online (Sandbox Code Playgroud)

我只需要知道关联是否存在(因此是lookup表)并且具有一对多的关系。我知道没有别的有关outside_data_id除了id本身和相关ticket_id

此外,我不想更改tickets表格,因为这只会影响少量的ticket_id's。

例子

outside_data_id = 1234
Run Code Online (Sandbox Code Playgroud)

可能与:

ticket_id = 321
ticket_id = 322
ticket_id = 900
Run Code Online (Sandbox Code Playgroud)

下面的查找表结构会起作用还是有更好的方法?

CREATE TABLE lookup
(
   outside_data_id integer, 
   ticket_id integer
)
Run Code Online (Sandbox Code Playgroud)

epi*_*fil 5

为此,您的表可以正常工作,但您可能想要添加索引。如果使用这个表的主要原因是获取一个outside_ticket_id并获得相应的ticket_id,我会添加以下聚集索引:

CREATE CLUSTERED INDEX [CL_Lookup_OD_ID] on [lookup](outside_data_id)
GO
Run Code Online (Sandbox Code Playgroud)

如果主要查找将是相反的方式(尝试从ticket_id 中查找outside_data_id)将聚集索引放在另一列上。

---- 哦,抱歉,刚注意到这是 Postgres。上面的语法是 SQL Server。对于 Postgres,在列上创建一个索引,然后发出 cluster 命令,如下所示:

CREATE INDEX IX_outside_data_id on lookup(outside_data_id);
CLUSTER lookup using IX_outside_data_id;
Run Code Online (Sandbox Code Playgroud)

您可能还想查看索引上的“填充因子”,具体取决于此处插入负载的重量。但这是一个值得自己探索的大话题......


Erw*_*ter 5

像你这样的结构可能应该用以下方法解决:

  • 一个多列主键上的约束-表(lookup)和
  • 一个外键约束引用的主键1 -表。

用于在一个方向上查找值的最佳索引由表的主键自动提供。lookup

CREATE TABLE ticket (
   ticket_id integer PRIMARY KEY  -- possibly serial instead of integer
 , stuff text
);

CREATE TABLE lookup (
   outside_data_id integer
 , ticket_id integer REFERENCES ticket(ticket_id)
      -- ON UPDATE CASCADE  -- optional
      -- ON DELETE CASCADE  -- optional
 , CONSTRAINT lookup_pkey PRIMARY KEY (outside_data_id, ticket_id)
);
Run Code Online (Sandbox Code Playgroud)

使用ticket_id描述性名称。

如果你 ..

只需要知道关联是否存在

...那么一个普通的外键 可能就是你所需要的。它会自动处理这些并提供额外的奖励,即无论如何都要强制执行关系完整性。加上更多选择。
它还坚持每一个都有 一个相关的项目filter_id,所以你可能无法使用它。

所需的实际索引取决于您的工作量,在多次阅读您的问题后,我仍然不清楚。特别是,多列索引中的列顺序(或与此相关的主键约束)是相关的 - 正如我们在此相关问题下深入讨论的那样。

为了获得最佳性能(忽略索引维护成本,假设表没有更新太多),如果您的查询双向进行,除了上面定义的主键之外,您还需要创建另一个索引:

CREATE INDEX lookup_reverse_idx(ticket_id, outside_data_id);
Run Code Online (Sandbox Code Playgroud)

虽然您可以仅使用 上的单列索引覆盖大多数其他用例ticket_id,但由于 PostgreSQL 存储中的数据对齐,索引中的两个整数列在磁盘上的大小与一个相同。因此,几乎没有任何额外收益的成本。

在旁边

使用不同 RDBMS 收集的经验并不总是适用于跨平台。

PostgreSQL没有CLUSTERED INDEX类似的 SQL server

PostgreSQL 的CLUSTER命令松散相关,但工作方式不同。这是一次性操作,不会使保持集群状态。它还完全重写了具有 a 的所有效果的表格VACUUM FULL(在 Postgres 9.0 之后的现代版本中)。

根据您的实际工作量,CLUSTER可能有用也可能没用。它可以用于查找多个相关行 ( outside_data_id-> ticket_id),尤其是对于更新不多的表。

FILLFACTOR但是,建议是好的,尤其是如果您使用CLUSTER-如果您使用UPDATE太多,这实际上可能会损害性能。