使用唯一约束来实现更简单的联接

时间:2018-08-27 19:15:46

标签: oracle performance join relational-database

这是一个概念性问题,因为我正在考虑针对频繁连接的一组表进行数据库设计的两种方法。

这是案例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)
);

将针对这些表集运行的常见查询如下: 案例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不需要联接。我的问题:

-我是否纠正这两个表结构强制执行相同的业务需求? -如果这样做,我该如何确定实施哪种情况?

我在理解不同关系表结构的性能提升/损失方面无能为力。这是在Oracle 12c上。

对于这种情况下的任何指导,以及在查询性能以及它们与约束和联接的关系方面可以遵循的一些其他资源或规则,我深表感谢。

谢谢!

1 个答案:

答案 0 :(得分:2)

那些不是等效模型。

请考虑表OBJECT中的以下两行:

OBJECT_ID    SCHEMA_ID
1            1
1            2

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

现在,如果您愿意让应用程序强制执行“ OBJECT_ID是唯一的”约束,那么您可以可以使用CASE B存储满足CASE A要求的数据。您可能不应该,但是可以。也就是说,您可以在CASE A中放入数据库的所有内容都可以在CASE B中放入数据库。

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

在案例A中-唯一约束是多余的-再次查看OBJECT表OBJECT_ID已经是唯一的。因此,您不需要在表上使用该约束。

您可能想要的是索引,其中前导列为SCHEMA_ID。那可能只是SCHEMA_ID或SCHEMA_ID和OBJECT_ID的索引。这为您提供SCHEMA_ID的典型查询提供了良好的数据库访问路径。同样,COL表也是如此-为了获得最佳性能,您可能希望索引的前导列为OBJECT_ID。

如果情况B是正确的,则可以添加索引以支持您的查询,也可以反转主键中字段的顺序-如果您始终按SCHEMA_ID进行过滤,则需要一个第一列为SCHEMA_ID的索引。主键始终具有关联的索引,因此您可以利用它。

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