为约束分配索引

时间:2014-12-30 19:45:44

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

我有一个为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;

问题(1)

从上面的代码中,USING INDEX行中的ALTER TABLE命令在做什么?是将第一行创建的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

2 个答案:

答案 0 :(得分:2)

Oracle

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

首次添加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中,我想这是不可能的。

答案 1 :(得分:0)

在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.