11

假设我需要一个带有帐户 ID 且没有其他信息的简单表。有两种方法可以做到:

id varchar(255) PRIMARY KEY

或者添加数字主键:

id int PRIMARY KEY
accountId varchar(255) UNIQUE NOT NULL

这两种方法的优点/缺点是什么?您会选择哪一种,为什么?

第一个解决方案对可维护性(如果我们需要更改单行的 id)和性能有什么影响?

4

3 回答 3

13

这归结为数据库世界中代理键自然键的争论。有关该主题的文本,请参见此处此处此处的示例。我认为这两种选择都是有效的,但在这种情况下,我会选择AccountID作为自然键(假设AccountID每个帐户都是唯一的,不会为空,并且不会受到更改),因为这意味着更少的开销。在这种情况下,我看不到代理键的附加值。

自然键:

  • 对用户有意义
  • 需要时很难改变
  • 可能导致在查询中需要更少的连接

代理键:

  • 对用户没有任何意义
  • 不受更改
  • 可能导致在查询中需要更多连接
  • 可能需要额外或更大的索引
于 2012-12-07T11:28:46.033 回答
2

不同之处在于 PRIMARY KEY 约束暗示/强制执行 NOT NULL CONSTRAINT。在第一个示例中,varchar(255)将有效提升为varchar(255) NOT NULL

DROP SCHEMA tmp CASCADE;
CREATE SCHEMA tmp ;
SET search_path=tmp;

CREATE TABLE pk
        ( id varchar(255) PRIMARY KEY
        );

CREATE TABLE uniq
        ( id int PRIMARY KEY
        , accountid varchar(255) UNIQUE
        );

INSERT INTO pk (id) VALUES(NULL);
INSERT INTO uniq (id, accountid) VALUES(1, NULL);

结果:

DROP SCHEMA
CREATE SCHEMA
SET
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "pk_pkey" for table "pk"
CREATE TABLE
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "uniq_pkey" for table "uniq"
NOTICE:  CREATE TABLE / UNIQUE will create implicit index "uniq_accountid_key" for table "uniq"
CREATE TABLE
ERROR:  null value in column "id" violates not-null constraint
INSERT 0 1

由于 PK (-->>NOT NULL) 约束,第一次插入失败;第二个成功。

于 2012-12-07T11:15:59.333 回答
1

如果该列的内容是唯一的(这似乎是 ID 的情况),则继续并将其设为主键,否则创建另一个数字列作为主键。

问候,

于 2012-12-07T11:00:20.260 回答