使用唯一约束来启用更简单的连接

using unique constraints to enable simpler joins

这是一个概念性问题,因为我正在考虑为一组经常连接的 table 数据库设计两种方法。

这是案例 A:

/*SCHEMA*/
CREATE TABLE SCHEMA (
SCHEMA_ID    INTEGER,
CONSTRAINT sch_pk PRIMARY KEY (SCHEMA_ID)
);

/*OBJECTS*/
CREATE TABLE OBJECT (
OBJECT_ID    INTEGER,
SCHEMA_ID    INTEGER NOT NULL,
CONSTRAINT obj_pk PRIMARY KEY (OBJECT_ID),
CONSTRAINT obj_sch_uniq UNIQUE (OBJECT_ID,SCHEMA_ID),
CONSTRAINT obj_fk FOREIGN KEY (SCHEMA_ID) REFERENCES SCHEMA(SCHEMA_ID)
);

/*COLUMNS*/
CREATE TABLE COL (
COL_ID      INTEGER,
OBJECT_ID   INTEGER,
CONSTRAINT col_pk PRIMARY KEY (COL_ID),
CONSTRAINT col_obj_uniq UNIQUE (COL_ID,OBJECT_ID),
CONSTRAINT col_fk FOREIGN KEY (OBJECT_ID) REFERENCES OBJECT(OBJECT_ID)
);

这是案例 B:

/*SCHEMA*/
CREATE TABLE SCHEMA (
schema_id               INTEGER,
CONSTRAINT schema_pk PRIMARY KEY (schema_ID),
);

/*OBJECTS*/
CREATE TABLE OBJECT (
object_id               INTEGER,
schema_id               INTEGER,
CONSTRAINT object_pk PRIMARY KEY (object_id,schema_id),
CONSTRAINT object_schema_fk FOREIGN KEY (schema_id) REFERENCES SCHEMA (schema_id)
);

/*COLUMNS*/
CREATE TABLE COL (
column_id               INTEGER,
object_id               INTEGER,
schema_id               INTEGER,
CONSTRAINT column_pk PRIMARY KEY (column_id,object_id,schema_id),
CONSTRAINT column_object_fk FOREIGN KEY (object_id,schema_id) REFERENCES OBJECT (object_id,schema_id)
);

针对这些 table 组的 运行 的常见查询如下: 案例A

SELECT *
FROM METADATA_CONTROL.COL
INNER JOIN METADATA_CONTROL.OBJECT ON METADATA_CONTROL.COL.OBJECT_ID = METADATA_CONTROL.OBJECT.OBJECT_ID
WHERE OBJECT.SCHEMA_ID = 101;

案例 B

SELECT *
FROM METADATA_CONTROL.COL
WHERE SCHEMA_ID = 101;

可以看出,CASE A 需要联接,CASE B 不需要。我的问题:

-我是否正确认为这两个 table 结构执行相同的业务需求? - 如果他们这样做,我如何确定要实施哪种情况?

我不太了解不同关系 table 结构的性能 gains/penalties。这是在 Oracle 12c 上。

我很感激在这种情况下的任何指导以及我可以遵循的一些额外的资源或规则,这些资源或规则与查询性能以及它们与约束和连接的关系有关。

谢谢!

这些不是等效模型。

考虑 table OBJECT 中的以下 2 行:

OBJECT_ID    SCHEMA_ID
1            1
1            2

您可以在案例 B 中插入两行。您不能在案例 A 中插入两行。毕竟主键是唯一的 - 所以 PRIMARY_KEY(OBJECT_ID) 意味着 OBJECT_ID在 OBJECT table 中是唯一的。

现在,如果您愿意让应用程序强制执行 "OBJECT_ID is unique" 约束,那么您 可以 使用案例 B 来存储满足案例 A 要求的数据。你可能不应该,但你可以。也就是说,你可以在 CASE A 中放入数据库的所有内容都可以在 CASE B 中放入数据库。反之则不然。

所以主要根据正确性在案例 A 和案例 B 之间进行选择。

在案例 A 中 - 唯一约束是多余的 - 再次查看 OBJECT table OBJECT_ID 已经是唯一的。所以你不需要对你的 table 进行限制。

您可能确实需要一个索引,其中前导列为 SCHEMA_ID。这可能只是 SCHEMA_ID 或 SCHEMA_ID 和 OBJECT_ID 上的索引。这为数据库提供了您提供 SCHEMA_ID 的典型查询的良好访问路径。 COL table 也是如此——为了获得最佳性能,您可能需要一个具有前导列 OBJECT_ID.

的索引

如果情况 B 是正确的,您可以添加索引来支持您的查询,或者反转主键中字段的顺序 - 如果您总是按 SCHEMA_ID 进行过滤,您需要一个索引其中第一列是 SCHEMA_ID。主键总是有一个关联的索引,所以你可以利用它。

基本上根据需求决定什么是正确的,然后优化性能。