我们从一个简单的主键开始:
SQL> CREATE TABLE books(
title VARCHAR2(10),
CONSTRAINT pk_title PRIMARY KEY(title))
ORGANIZATION INDEX;
Table created.
Run Code Online (Sandbox Code Playgroud)
然后意识到它不是唯一的。比如说,一本书可以以相同的标题重新发行:
SQL> ALTER TABLE books ADD(release_date DATE NOT NULL);
Table altered.
Run Code Online (Sandbox Code Playgroud)
现在要插入重新发布的书,我们必须以某种方式放松标题的唯一性。
但是由于表被索引组织,我无法删除和重新创建 PK:
SQL> ALTER TABLE books DROP PRIMARY KEY;
ALTER TABLE books DROP PRIMARY KEY
*
ERROR at line 1:
ORA-25188: cannot drop/disable/defer the primary key constraint for
index-organized tables or sorted hash cluster
Run Code Online (Sandbox Code Playgroud)
我也无法设法就地扩展现有密钥:
SQL> CREATE UNIQUE INDEX pk_title_date ON books(title, release_date);
Index created.
SQL> ALTER TABLE books MODIFY PRIMARY KEY USING INDEX pk_title_date;
ALTER TABLE books MODIFY PRIMARY KEY USING INDEX pk_title_date
*
ERROR at line 1:
ORA-14196: Specified index cannot be used to enforce the constraint.
Run Code Online (Sandbox Code Playgroud)
我有哪些选择?是否可以不移动数据或重新创建表(实际表很大)?
索引组织表(IOT)就是这样;没有“真实”表的索引。除主键之外的所有数据都只是“附加”到主键,因此,例如,如果您有一个包含 6 列的 IOT,其中 2 列构成主键,则在幕后您只有一个包含 6 列的索引,其中前两列使其独一无二。
所以,抱歉,解决这个问题的唯一方法是重新创建表;为了缩短重建时间,请暂时禁用日志记录。您不能使用append
IOT 表插入提示来强制直接路径插入:
SQL> CREATE TABLE books_new (
title VARCHAR2(10),
release_date DATE NOT NULL,
CONSTRAINT pk_title PRIMARY KEY(title,release_date))
ORGANIZATION INDEX NOLOGGING;
SQL> INSERT INTO books_new
(SELECT title, '01-Jan-1980' FROM books);
SQL> ALTER TABLE books_new LOGGING;
SQL> ALTER TABLE books RENAME TO books_old;
SQL> ALTER TABLE books_new RENAME TO books;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6872 次 |
最近记录: |