【问题标题】:Oracle: Finding Primary Keys - PK and NNOracle:查找主键 - PK 和 NN
【发布时间】:2015-10-14 10:14:45
【问题描述】:

我正在使用数据库,并被告知表 USERS 有一个主键 - USERID。使用ALL_CONS_COLS 给了我以下信息:

OWNER   | TABLE_NAME | CONSTRAINT_NAME | COLUMN_NAME | POSITION
----------------------------------------------------------------
MONSTER |   USERS    |   USER_ID_PK    |   USERREF   |   2
MONSTER |   USERS    |   USER_ID_NN    |   USERID
MONSTER |   USERS    |   USER_ID_PK    |   USERID    |   1

这表明 PK 是由以下各项组成的组合:USERREFUSERID

有几件事我没有遵循:

为什么USERID 既有NOT NULL 约束又有PK 约束? PK 定义为 NN。 其次,由于USERIDNN 约束,为什么USERREF 没有NN 约束? 第三,为什么CONSTRAINT_NAME“建议”PKUSER_IDUSERID),即为什么约束以单列命名; USERS_PK 不是更好的约束名称吗?

那么,归根结底,它是不是一个 Composite PK

【问题讨论】:

  • 大多数问题的答案是(可能):因为有人以这种方式创建了它(尤其是名称和 NN 约束)
  • 谢谢!那么它是复合PK 吗?

标签: database oracle primary-key composite-primary-key


【解决方案1】:

那么,最终,它是否是复合 PK?

是的。主键一起定义在两列上。该位置将告诉您领先的列。 USER_ID_PK 主键约束在 USERID 上定义为前导列,后跟 USERREF

为什么 USERID 既有 NOT NULL 约束又有 PK 约束?

因为有人在 主键 列上显式创建了 NOT NULL 约束。

让我们测试一下。

单主键

SQL> create table t(a number primary key);

Table created.

SQL> SELECT a.table_name,
  2    b.column_name,
  3    a.constraint_type,
  4    b.position
  5  FROM user_constraints a
  6  JOIN user_cons_columns b
  7  ON a.owner             = b.owner
  8  AND a.constraint_name  = b.constraint_name
  9  AND a.table_name       = b.table_name
 10  AND a.constraint_type IN ('P', 'C');

TABLE_NAME COLUMN_NAM C   POSITION
---------- ---------- - ----------
T          A          P          1

复合主键

SQL> drop table t purge;

Table dropped.

SQL> create table t(a number, b number);

Table created.

SQL> alter table t add constraint t_pk PRIMARY KEY(a,

Table altered.

SQL> SELECT a.table_name,
  2    b.column_name,
  3    a.constraint_type,
  4    b.position
  5  FROM user_constraints a
  6  JOIN user_cons_columns b
  7  ON a.owner             = b.owner
  8  AND a.constraint_name  = b.constraint_name
  9  AND a.table_name       = b.table_name
 10  AND a.constraint_type IN ('P', 'C');

TABLE_NAME COLUMN_NAM C   POSITION
---------- ---------- - ----------
T          A          P          1
T          B          P          2

主键且不为空

SQL> drop table t purge;

Table dropped.

SQL> create table t(a number primary key not null);

Table created.

SQL> SELECT a.table_name,
  2    b.column_name,
  3    a.constraint_type,
  4    b.position
  5  FROM user_constraints a
  6  JOIN user_cons_columns b
  7  ON a.owner             = b.owner
  8  AND a.constraint_name  = b.constraint_name
  9  AND a.table_name       = b.table_name
 10  AND a.constraint_type IN ('P', 'C');

TABLE_NAME COLUMN_NAM C   POSITION
---------- ---------- - ----------
T          A          C
T          A          P          1

【讨论】:

  • 什么是前导列,它有什么作用(如果有的话)?
  • “前导列”是指本文中的第一列。但是,它在串联(复合)索引中具有重要意义。这超出了你的问题范围。不过,如果您有兴趣,请查看orafaq.com/tuningguide/concatenated%20indexes.html
猜你喜欢
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-15
  • 2010-11-11
  • 2013-04-23
相关资源
最近更新 更多