其中名为 SYS_C 的 oracle 外键约束来自

where oracle foreign key constraint named SYS_C comming from

我的数据库是 oracle 10.2,我的创建 table sql 是这样的:

create table T_EP_SYS_COMPANY
(
  company_id      NUMBER not null,
  company_name    VARCHAR2(30),
  company_address VARCHAR2(100),
  is_in_use       VARCHAR2(1),
  is_canceled     VARCHAR2(1),
  is_headquarter  VARCHAR2(1),
  account_id      NUMBER not null
)
tablespace USERS
  pctfree 10
  maxtrans 255
storage
  (
initial 64K
minextents 1
maxextents unlimited
);

alter table T_EP_SYS_COMPANY
  add constraint PK_ESHOP_SYS_COMPANY primary key (COMPANY_ID)
  using index 
  tablespace USERS
  pctfree 10
  initrans 2
  maxtrans 255
  storage
  (
    initial 64K
    minextents 1
    maxextents unlimited
  );
alter table T_EP_SYS_COMPANY
  add constraint FK_SYS_COMPANY_PAY_ACCOUNT foreign key (ACCOUNT_ID)
 references T_EP_PAY_ACCOUNT (ACCOUNT_ID);

但在我的数据库中,我必须在 "account_id" 列上有 2 个 FK:

owner       constraint_name          table_name      column_name  position
ESHOPV2  SYS_C009725                T_EP_SYS_COMPANY    ACCOUNT_ID    null
ESHOPV2  FK_SYS_COMPANY_PAY_ACCOUNT T_EP_SYS_COMPANY    ACCOUNT_ID     1 

为什么有2个FK?我确实重命名了 table 名称,重命名 ddl 是否与此有关?

它们不都是外键约束。 The SYS_C is a system-generated name for a constraint you didn't explicitly name;在这种情况下,您的非空检查。您可以在创建后立即看到这些:

create table T_EP_SYS_COMPANY
(
  company_id      NUMBER not null,
  company_name    VARCHAR2(30),
  company_address VARCHAR2(100),
  is_in_use       VARCHAR2(1),
  is_canceled     VARCHAR2(1),
  is_headquarter  VARCHAR2(1),
  account_id      NUMBER not null
);

select uc.constraint_name, uc.constraint_type, ucc.column_name, ucc.position
from user_constraints uc
join user_cons_columns ucc on ucc.constraint_name = uc.constraint_name
where uc.table_name = 'T_EP_SYS_COMPANY';

CONSTRAINT_NAME                CONSTRAINT_TYPE COLUMN_NAME     POSITION
------------------------------ --------------- --------------- --------
SYS_C0093988                   C               COMPANY_ID               
SYS_C0093989                   C               ACCOUNT_ID               

约束类型是C,表明它是一个检查约束。您可以通过显式添加检查约束来命名它们,而不是将它们指定为 'not null' 但没有真正的好处 - 您永远不需要通过名称引用它们,例如暂时禁用它们。

添加主键和外键后,您也会看到它们:

alter table T_EP_SYS_COMPANY
  add constraint PK_ESHOP_SYS_COMPANY primary key (COMPANY_ID);

alter table T_EP_SYS_COMPANY
  add constraint FK_SYS_COMPANY_PAY_ACCOUNT foreign key (ACCOUNT_ID)
 references T_EP_PAY_ACCOUNT (ACCOUNT_ID);

select uc.constraint_name, uc.constraint_type, ucc.column_name, ucc.position
from user_constraints uc
join user_cons_columns ucc on ucc.constraint_name = uc.constraint_name
where uc.table_name = 'T_EP_SYS_COMPANY';

CONSTRAINT_NAME                CONSTRAINT_TYPE COLUMN_NAME     POSITION
------------------------------ --------------- --------------- --------
SYS_C0093988                   C               COMPANY_ID               
SYS_C0093989                   C               ACCOUNT_ID               
PK_ESHOP_SYS_COMPANY           P               COMPANY_ID             1 
FK_SYS_COMPANY_PAY_ACCOUNT     R               ACCOUNT_ID             1 

对于 'primary key' 和 'referential integrity',它们具有约束类型 P 和 R。

详细了解 types of integrity constraints and how they are shown in the data dictionary

owner       constraint_name          table_name      column_name  position
ESHOPV2  SYS_C009725                T_EP_SYS_COMPANY    ACCOUNT_ID    null
ESHOPV2  FK_SYS_COMPANY_PAY_ACCOUNT T_EP_SYS_COMPANY    ACCOUNT_ID     1

why there are 2 FKs?

SYS_C009725 不是外键约束。它是 CHECK 约束 NOT NULL 条件。如果您看到 CONSTRAINT_TYPE,那么您会看到它是 C。而你看到的名字SYS_C是因为它是系统生成的名字.

太简单了,让我们看一个小例子:

SQL> CREATE TABLE t(
  2  ID NUMBER NOT NULL
  3  );

Table created.

SQL>
SQL> SELECT constraint_name,
  2    constraint_type,
  3    table_name,
  4    search_condition
  5  FROM user_constraints
  6  WHERE table_name ='T';

CONSTRAINT_NAME CONSTRAINT_TYPE TABLE_NAME SEARCH_CONDITION
--------------- --------------- ---------- ----------------
SYS_C0010726    C               T          "ID" IS NOT NULL

SQL>