【问题标题】:Assigning an index to a constraint将索引分配给约束
【发布时间】:2015-02-26 23:30:00
【问题描述】:

我有一个为 Oracle 数据库编写的脚本,我将其转换为在 SQL Server 中工作,我有两个关于特定代码部分的问题。

Oracle 脚本中,我有以下代码:

CREATE UNIQUE INDEX "PK_PORTALROLES" ON "PORTAL_ROLE" ("ROLE_NAME");

ALTER TABLE "PORTAL_ROLE" ADD CONSTRAINT "PK_PORTALROLES" 
      PRIMARY KEY ("ROLE_NAME") USING INDEX  ENABLE;

问题(一)

根据上面的代码,ALTER TABLE 行中的USING INDEX 命令在做什么?是将第一行创建的UNIQUE INDEX 分配给新创建的CONSTRAINT 还是CONSTRAINT 在创建时获得一个新的UNIQUE INDEX

问题(2)

为了在 SQL Server 中复制这一点,我将 CREATE UNIQUE INDEX 行注释掉,如下所示:

--CREATE UNIQUE INDEX "PK_PORTALROLES" ON "PORTAL_ROLE" ("ROLE_NAME");

然后将ALTER TABLE 行替换为:

ALTER TABLE "PORTAL_ROLE" ADD CONSTRAINT "PK_PORTALROLES" PRIMARY KEY ("ROLE_NAME");

我了解在 SQL Server 中创建 PRIMARY KEY CONSTRAINT 时会自动创建 UNIQUE INDEX。那么上面的那一行SQL Server代码和上面的两行Oracle代码是不是一样的呢?

编辑

最后一个问题。 Oracle 和 SQL Server 中有没有办法将现有的INDEX 分配给CONSTRAINT

【问题讨论】:

    标签: sql sql-server oracle sql-server-2008 oracle11g


    【解决方案1】:

    甲骨文

    如果要添加PK约束的列上有多个索引,我们可以使用“USING INDEX”选择性地选择与PK关联的索引。此子句可用于 while:

    首次添加 PK 约束(使用“ALTER TABLE”命令)。

    CREATE TABLE tbl_test ( col_1 NUMBER, 
                            col_2 NUMBER,
                            col_3 NUMBER);
    
    CREATE INDEX idx_col_1_2 ON tbl_test(col_1, col_2);
    
    CREATE INDEX idx_col_1_3 ON tbl_test(col_1, col_3);
    
    CREATE UNIQUE INDEX idx_col_1 ON tbl_test(col_1);
    
    -- Forcing oracle to use the unique index "IDX_COL_1"
    ALTER TABLE tbl_test ADD CONSTRAINT tbl_test_pk PRIMARY KEY(col_1) 
    USING INDEX idx_col_1;
    
    SELECT constraint_name, constraint_type, index_name
      FROM user_constraints
     WHERE table_name = 'TBL_TEST';
    
    -- CONSTRAINT_NAME | CONSTRAINT_TYPE | INDEX_NAME
    -- TBL_TEST_PK     | P               | IDX_COL_1
    

    如果呢?如果您不使用 USING INDEX 子句

    ALTER TABLE tbl_test ADD CONSTRAINT tbl_test_pk PRIMARY KEY(col_1);
    

    -- 虽然存在唯一索引,但 oracle 已经选择了第一个索引

    SELECT constraint_name, constraint_type, index_name
      FROM user_constraints
     WHERE table_name = 'TBL_TEST';
    
    -- CONSTRAINT_NAME | CONSTRAINT_TYPE | INDEX_NAME
    -- TBL_TEST_PK     | P               | IDX_COL_1_2
    

    这表明与 PK 约束相关的索引不必是唯一的。

    但在 SQLServer 中隐式 CLUSTERED INDEX 将在任何列上定义主键时创建

    所以关于你的最后一个问题。在 Oracle 中,您可以将我们创建的索引分配给我们将来创建的约束。 在 SQLServer 中我猜这是不可能的。

    【讨论】:

    • 在 SQL Server 中,只有当表还没有聚集索引时,PK 才会聚集。如果一个表已经有一个聚集索引,它将被保留。
    【解决方案2】:

    在Oracle中,你可以这样做

    alter table PORTAL_ROLE add constraint pk_portalroles primary key('ROLE_NAME');
    

    它会为您创建唯一索引。但是当您删除或禁用(!)约束时,它将删除该索引。为避免这种情况(或为索引提供一些自定义名称,或使用非唯一索引等),通常在您的代码中分两步完成(如 ORACLE 推荐的那样)。

    Q1:约束将使用现有索引。

    Q2:是的,对于 SQL Server 来说已经足够了。

    When you specify a unique constraint on one or more columns, Oracle implicitly creates an index on the unique key. If you are defining uniqueness for purposes of query performance, then Oracle recommends that you instead create the unique index explicitly using a CREATE UNIQUE INDEX statement. You can also use the CREATE UNIQUE INDEX statement to create a unique function-based index that defines a conditional unique constraint.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-15
      • 2011-04-28
      • 2021-09-12
      • 2021-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多