Phi*_*ord 6 postgresql database-design clustered-index referential-integrity index-tuning
我有一个tickets表id,我需要将它关联到一个查找表,其中该数据的对应项是另一个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)
为此,您的表可以正常工作,但您可能想要添加索引。如果使用这个表的主要原因是获取一个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)
您可能还想查看索引上的“填充因子”,具体取决于此处插入负载的重量。但这是一个值得自己探索的大话题......
像你这样的结构可能应该用以下方法解决:
lookup)和用于在一个方向上查找值的最佳索引由表的主键自动提供。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太多,这实际上可能会损害性能。
| 归档时间: |
|
| 查看次数: |
5119 次 |
| 最近记录: |