Oracle:查找主键 - PK 和 NN

Oracle: Finding Primary Keys - PK and NN

我正在使用数据库并被告知 Table 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 "suggesting" 而PKUSER_ID (USERID),即为什么约束以单列命名; USERS_PK 不是更好的约束名称吗?

所以,最终,它是否是复合 PK

So, ultimately, is it a Composite PK or not?

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

Why does USERID have both a NOT NULL constraint and also a PK constraint?

因为有人在 主键 列上明确创建了 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

主键和 NOT NULL

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