Postgresql
bigints 上的複合索引
我有一個使用者關係表,它基本上儲存了使用者的所有單向關係。例如,使用者A關注使用者B;使用者 X阻止使用者 Y
使用者 ID:
使用者的 id 是bigints。這不像我認為使用整數真的會遇到瓶頸(除非我的應用程序增長到超過 20 億使用者,那就是:)),但據我了解,如果我整合社交網路註冊,Facebook 使用 bigints對於他們的使用者 ID,因此我必須將使用者的 ID 保持為 bigint。
索引:
起初我想為兩個使用者(相關和相關)創建一個複合索引,但是由於兩個索引都是 bigint,意味著每個 8 個字節,儲存這樣一個怪異的索引不是浪費嗎?我最終只留下了一個列索引,但不確定在這種情況下這是否是最明智的決定。
我還想到了一個帶有覆蓋索引的變體 - 但在這種情況下,relation_type(follow, block) 不會成為索引/過濾的一部分,所以也許我應該將它包含在復合索引中,但是我會有 8+8+ 4字節的索引。在這種情況下,我不清楚空間和時間之間的權衡。對此事有任何想法將不勝感激。
第一個變體(單列索引):
CREATE TABLE user_relations ( relating_user_id bigint NOT NULL, related_user_id bigint NOT NULL, relation_type smallint NOT NULL, created_at default current_timestamp, PRIMARY KEY (relating_user_id), FOREIGN KEY (relation_type) references user_relations_types (id) -- will having only one index affect the performance really ? -- should I include the type into the composite type ? );
第二種變體(使用覆蓋索引並省略 PK):
CREATE TABLE user_relations ( relating_user_id bigint NOT NULL, related_user_id bigint NOT NULL, relation_type smallint NOT NULL, created_at default current_timestamp, FOREIGN KEY (relation_type) references user_relations_types (id), CREATE UNIQUE INDEX relating_user_related_user_relation_type_idx ON user_relations (relating_user_id, related_user_id) INCLUDE (relation_type); -- should I include the type into the composite type ? );
索引使用空間,16 字節的密鑰無需擔心。
user_relations
所以你應該在 on上定義主鍵(relating_user_id, related_user_id)
。如果您需要按 搜尋relation_type
,將列放入列表將無濟於事INCLUDE
,因為此類列不能用作索引掃描的過濾器。我看到兩個選項:
- 除了上面建議的主鍵之外,在
(relating_user_id, relation_type)
和上有額外的索引(related_user_id, relation_type)
。- 如果您想擁有更少的索引,請定義主鍵
(relating_user_id, relation_type, related_user_id)
並僅定義一個附加索引。如果數據庫允許同一使用者之間存在幾種不同的關係,也許您可以接受它。要定義哪些索引的決定因素應該是您必須經常有效地服務的查詢。設計這些查詢,問題會變得更容易。