0

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

4 回答 4

4

主键应遵循您的业务规则,仅此而已。由于这样的照片没有“真实”(即自然)主键,因此使用序列作为 PK 绝对有意义。

扩展主键user_id没有任何意义,也没有任何目的(因为photo_id无论如何都是唯一的,你只会增加索引维护的开销)。由于user_id是索引中的第二列,它不太可能用于限制user_id(不是不可能但不太可能)的查询

所以我会坚持使用 PKphoto_id并添加一个索引user_id(无论如何,索引外键列总是一个好主意)。

于 2012-08-26T15:30:11.223 回答
2

所写的主键不能用于按 user_id 进行搜索,因为 user_id 是键中的第二列。

您的第二个选项是最好的 - 仅 photo_id 上的主键,因为这是记录的唯一标识符,并在 user_id 上为您的查询添加单独的索引。

于 2012-08-26T15:29:56.510 回答
0

如果您有自动递增的 ID,我认为您不需要 user_id 作为主键。你为什么不在 user_id 上使用外键到你的用户表(我猜你有一个)?

于 2012-08-26T15:34:33.503 回答
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,它的唯一性不足以作为主键, and 也不会FirstNameLastName因此在这种情况下,至少会使用 3 列。当然,最好有一个IDorPersonID列并将其用作主键。

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

于 2012-08-26T16:07:08.153 回答