postgresql - 我是否需要复合主键的索引,其中每列都是外键
问题描述
当我创建表用户时:
pk
id | int
和表友:
pk, fk | pk, fk
user_id | friend_id
据我了解,复合 pk 在内部创建唯一索引 user_id+friend_id,该索引用于 user_id 外键。但是我是否需要为friend_id创建索引,因为复合pk朋友表上的索引不适用于friend_id(它是复合pk中的第二个)?
SQL:
CREATE TABLE public."user"
(
id integer NOT NULL DEFAULT nextval('user_id_seq'::regclass),
)
CREATE TABLE public.user_friend
(
user_id integer NOT NULL,
friend_id integer NOT NULL,
CONSTRAINT user_friend_pkey PRIMARY KEY (user_id, friend_id),
CONSTRAINT user_friend_friend_id_fkey FOREIGN KEY (friend_id)
REFERENCES public."user" (id) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE CASCADE,
CONSTRAINT user_friend_user_id_fkey FOREIGN KEY (user_id)
REFERENCES public."user" (id) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE CASCADE
)
CREATE INDEX fki_user_friend_friend_id_fkey
ON public.user_friend USING btree
(friend_id ASC NULLS LAST)
TABLESPACE pg_default;
解决方案
据我了解,复合 pk 会在内部创建唯一索引 user_id+friend_id
是的。
该索引用于 user_id 外键。
不完全是,不。
这里有两种情况:
- 一个
INSERT
或UPDATE
在user_friend
桌子上。当然,它必须检查表的主键(并将user_friend_pkey
为此使用索引)。对于外键约束,这将只需要检查表中是否存在user_id
和friend_id
值user
,并将使用由user
的主键创建的索引。 - 一个
UPDATE
或DELETE
在user
桌子上。它将必须检查user_friend
表中是否引用了旧值,并根据CASCADE
orRESTRICT
策略执行操作。要在 中找到这一行user_friend
,它将使用 onuser_id
和 on的索引(friend_id
如果存在)。
但是我需要为friend_id创建索引吗,因为复合pk朋友表上的索引不适用于friend_id
friend_id
是的,如果没有额外的索引,查找速度很慢。仅当您想查找以 x 为朋友的用户时,或者当更新/删除user
速度不慢时,您才需要此选项。
推荐阅读
- next.js - 在 NextJS 中更新 Fetch API 调用的结果
- excel - 在 vba 中创建一个动态公式,其中包含一个变量
- javascript - 下一个和上一个按钮 javascript
- javascript - 如何访问另一个对象深处的对象
- php - PHP 中 json_encode() 返回的神秘错误代码
- python - ModuleNotFoundError:没有名为“a”的模块
- sql-server - 过滤过去 n 周
- onclicklistener - 用于空白屏幕 android studio 的 onclicklistener
- javascript - 深度自引用对象的属性
- c# - 我的构建大小随机翻倍 Unity3d Andriod