此表包含用户的照片(缩略图和完整照片) 大多数查询都有一个“WHERE user_id =?”条件。
CREATE TABLE photos (
"photo_id" serial, -- serial is postgres' autoincrement
"user_id" integer not null, -- foreign key to users table
"filename_thumbnail_50" varchar not null,
"filename_thumbnail_75" varchar not null, -- 75px x 75px thumbnail
"filename_full" varchar not null,
PRIMARY KEY ("photo_id", "user_id")
);
此用例的最佳设计和/或性能设计是什么:
- 如上例所示的两列主键?
- 一个主键(photo_id)和user_id上的索引?
答案 0 :(得分:4)
主键应遵循业务规则而不是其他任何内容。由于照片没有“真实”(即自然)主键,因此使用串口作为PK绝对有意义。
使用user_id
扩展主键没有任何意义,也没有任何意义(因为photo_id
无论如何都是唯一的,你只会增加索引维护的开销)。并且user_id
是索引中的第二列,它不太可能用于限制user_id
的查询(不是不可能但不太可能)
所以我会坚持使用photo_id
上的PK并在user_id
上添加索引(无论如何索引外键列总是一个好主意。)
答案 1 :(得分:2)
写入的主键不能用于user_id搜索,因为user_id是键中的第二列。
您的第二个选项最好 - 仅限photo_id上的主键,因为这是记录的唯一标识符,并为您的查询在user_id上添加单独的索引。
答案 2 :(得分:0)
如果你有一个增加的ID,我认为你不需要user_id作为主键。为什么不在user_id上使用forign键到你的用户表(我猜你有一个)?
答案 3 :(得分:0)
如果您有专门用于识别目的的列(在本例中为photo_id),则不需要第二个键列。
如果您的情况可能有多个具有相同photo_id和不同user_ids的记录,那么我认为最好有一个中间表来创建多对多关系并保留单个主键。例如:
CREATE TABLE photos (
"photo_id" serial,
-- other columns
PRIMARY KEY ("photo_id")
);
CREATE TABLE users (
"user_id" serial,
-- other columns
PRIMARY KEY ("user_id")
);
CREATE TABLE photos_users (
"photo_user_id" serial,
"photo_id" integer, -- not sure if this datatype is correct for postgres
"user_id" integer, -- not sure if this datatype is correct for postgres
PRIMARY KEY ("photo_user_id")
);
据我所知 - 在没有特定id列的情况下需要第二个关键列,如果只使用了1个密钥,则可能会出现重复。下面是一个例子:
CREATE TABLE Person (
"FirstName" varchar NOT NULL,
"LastName" varchar NOT NULL,
"PostalCode" varchar NOT NULL,
PRIMARY KEY ("FirstName", "LastName", "PostalCode")
);
在上述情况下,FirstName
不具有作为主键的唯一性,FirstName
和LastName
也不会,因此在这种情况下将使用至少3列。当然,最好有一个ID
或PersonID
列并将其用作主键。
就性能而言,主键不会产生太大影响。担心索引。确保将在WHERE
子句或JOIN
或AGGREGATE
中使用的任何列都有索引。