首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >收缩甲骨文中的列

收缩甲骨文中的列
EN

Stack Overflow用户
提问于 2011-10-12 14:14:14
回答 3查看 4.3K关注 0票数 5

假设我有一个具有以下定义的表

代码语言:javascript
运行
复制
create table dummy (col1 number(9) not null)

这个dummy.col1中的所有值都有7位长。现在,我希望使用alter命令将这一列的长度从9-7减少。Oracle给出了一个错误,即要修改的列必须为空,以降低精度或缩放。合乎道理。

我想问一下,有什么工作可以缩小栏目的大小吗?

  • I无法删除列中的值。
  • I不能将值从本列复制到另一列,因为它有数万亿的数据。
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-10-12 14:39:36

列大小与数据的物理存储方式无关(它们是可变长度)。

例如,一个数字(2)中的“23”如果存储在一个数字(38)中,将占用完全相同的空间。

它纯粹是对可以存储在列中的最大数量的约束,因此您只需在列上添加一个约束:

代码语言:javascript
运行
复制
ALTER TABLE dummy ADD 
CONSTRAINT c1
CHECK (col1 < 9999999)
ENABLE
VALIDATE;

如果您希望它运行得更快一些,那么显然将VALIDATE更改为NOVALIDATE,这将不会检查现有数据的有效性。

票数 5
EN

Stack Overflow用户

发布于 2011-10-12 16:58:18

凯文的回答很好。

唯一的其他方法就是

重命名现有列,

创建具有旧名称和新大小的新列,

发出一个update语句来填充新字段(您说过不能这样做)

然后删除重命名的列。

您确定某个周末无法找到一些停机时间来执行此任务吗?

票数 3
EN

Stack Overflow用户

发布于 2012-08-14 19:26:06

解决方案#1

下面的解决方案保持原来的列顺序。

我发现这是很重要的,特别是如果有屏蔽的SQL语句。

在那里(中间层、客户层)指向执行隐式操作的数据库。

选择。

代码语言:javascript
运行
复制
SELECT * 
FROM tableName
WHERE ...; 

INSERT INTO copyTableName(column1,column2,column3,...)  
   SELECT * 
   FROM tableName
   WHERE ...;

下面是:

生成DDL

  1. 包含要调整
  2. 列大小的表--所有关系约束、索引、检查约束、触发引用该表。
  3. 引用该表主键的其他表的所有外键。

确保每个表引用对象DDL是独立的,与

创建表DDL。

你会有这样的东西

代码语言:javascript
运行
复制
/* 1. The table containing the column you intend to resize */
CREATE TABLE tableName
(
  column1 TYPE(size) [DEFAULT value] [NOT] NULL,
  column2 TYPE(size) [DEFAULT value] [NOT] NULL,
  column3 TYPE(size) [DEFAULT value] [NOT] NULL,
  ...
)
TABLESPACE tsName
[OPTIONS];

/* 2. All the relationship constraints, indexes, check constraints, triggers that reference that table. */
CREATE INDEX indexName ON tableName
(column1)
NOLOGGING
TABLESPACE INDX
NOPARALLEL;

CREATE INDEX compositeIndexName ON tableName
(column1,column2,...)
NOLOGGING
TABLESPACE INDX
NOPARALLEL;

CREATE UNIQUE INDEX pkName ON tableName
(column2)
NOLOGGING
TABLESPACE INDX
NOPARALLEL;

ALTER TABLE tableName ADD (
  CHECK (column4 IS NOT NULL));

ALTER TABLE tableName ADD (
  CONSTRAINT pkName
 PRIMARY KEY
 (column2)
    USING INDEX 
    TABLESPACE INDX);

ALTER TABLE tableName ADD (
  CONSTRAINT fkName
 FOREIGN KEY (column2) 
 REFERENCES otherTable (column2));

/* 3. All the foreign keys of other tables that reference the primary key of this table. */
ALTER TABLE otherTableName ADD (
  CONSTRAINT otherTableFkName
 FOREIGN KEY (otherTableColumn2) 
 REFERENCES tableName (column1));

只复制CREATE TABLE语句,更改表名和

缩小要修改的列的大小:

代码语言:javascript
运行
复制
CREATE TABLE tableName_YYYYMMDD
(
  column1 TYPE(size)         [DEFAULT value] [NOT] NULL,
  column2 TYPE(reducedSize)  [DEFAULT value] [NOT] NULL,
  column3 TYPE(size)         [DEFAULT value] [NOT] NULL,
  ...
)
TABLESPACE tsName
[OPTIONS];

tableName中的数据插入tableName_YYYYMMDD

代码语言:javascript
运行
复制
INSERT /* APPEND */ INTO tableName_YYYYMMDD(
  column1 ,
  column2 ,
  column3 ,
  ...     )
    SELECT
      column1 ,
      column2 ,
      column3 ,
      ...     
    FROM tableName;
COMMIT;

删除引用原始表的所有对象。

另外,删除引用tableName主键pkName的所有外键。

别担心,您已经保存了DDL,这样就可以重新创建它们了。

注意,我在从tableName复制数据后删除了索引。

我这样做是因为其中一个索引可能会在

以上选择使操作完成速度更快。

代码语言:javascript
运行
复制
DROP INDEX indexName                                        ;
DROP INDEX compositeIndexName                               ;
DROP UNIQUE INDEX pkName                                    ;
ALTER TABLE tableName DROP CONSTRAINT pkName                ;
ALTER TABLE tableName DROP CONSTRAINT fkName                ;
ALTER TABLE otherTableName DROP CONSTRAINT otherTableFkName ;

放下原来的桌子。

代码语言:javascript
运行
复制
DROP TABLE tableName;

重命名新表。

代码语言:javascript
运行
复制
ALTER TABLE tableName_YYYYMMDD RENAME TO tableName;

重新创建以前保存的DDL语句中的所有引用对象。

代码语言:javascript
运行
复制
/* 2. All the relationship constraints, indexes, check constraints, triggers that reference that table. */
CREATE INDEX indexName ON tableName
(column1)
NOLOGGING
TABLESPACE INDX
NOPARALLEL;

CREATE INDEX compositeIndexName ON tableName
(column1,column2,...)
NOLOGGING
TABLESPACE INDX
NOPARALLEL;

CREATE UNIQUE INDEX pkName ON tableName
(column2)
NOLOGGING
TABLESPACE INDX
NOPARALLEL;

ALTER TABLE tableName ADD (
  CHECK (column4 IS NOT NULL));

ALTER TABLE tableName ADD (
  CONSTRAINT pkName
 PRIMARY KEY
 (column2)
    USING INDEX 
    TABLESPACE INDX);

ALTER TABLE tableName ADD (
  CONSTRAINT fkName
 FOREIGN KEY (column2) 
 REFERENCES otherTable (column2));

/* 3. All the foreign keys of other tables that reference the primary key of this table. */
ALTER TABLE otherTableName ADD (
  CONSTRAINT otherTableFkName
 FOREIGN KEY (otherTableColumn2) 
 REFERENCES tableName (column1));

解决方案#2

保持列的顺序,但不要重建可能包含column2的非唯一使用的PK索引。

代码语言:javascript
运行
复制
ALTER TABLE tableName ADD (column2Copy TYPE(reducedSize));

UPDATE      tableName SET column2Copy = column2;

ALTER TABLE tableName MODIFY (column2 TYPE(size) NULL);

ALTER TABLE tableName DROP CONSTRAINT pkName;

DROP INDEX  pkName;

UPDATE      tableName SET column2 = null;

ALTER TABLE tableName MODIFY (column2 TYPE(reducedSize));

UPDATE      tableName SET column2 = column2Copy;

ALTER TABLE tableName DROP COLUMN column2Copy;

CREATE UNIQUE INDEX pkName ON tableName
(column2)
NOLOGGING
TABLESPACE INDX
NOPARALLEL;

ALTER TABLE tableName ADD (
  CONSTRAINT pkName
 PRIMARY KEY
 (column2)
    USING INDEX 
    TABLESPACE INDX);

COMMIT;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7741468

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档