两列作为主键或一列作为PK +索引?

时间:2012-08-26 15:16:04

标签: sql database postgresql primary-key normalization

此表包含用户的照片(缩略图和完整照片)     大多数查询都有一个“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上的索引?

4 个答案:

答案 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不具有作为主键的唯一性,FirstNameLastName也不会,因此在这种情况下将使用至少3列。当然,最好有一个IDPersonID列并将其用作主键。

就性能而言,主键不会产生太大影响。担心索引。确保将在WHERE子句或JOINAGGREGATE中使用的任何列都有索引。