【问题标题】:Alter table modify column vs. multiply values query更改表修改列与乘值查询
【发布时间】:2012-10-10 10:50:48
【问题描述】:

我的应用程序与一个表有 100 万条记录的 Oracle 数据库进行交互。问题是:

在该表中,我们有一列用于数字整数类型。我们想要存储浮点值(2 位)。我们可以通过乘以 100(来自应用程序)并将它们存储在该列中或修改列数据来实现类型。问题是:

什么需要更少的时间? alter table modify column 或者查询(update table set column = 100*val)。

【问题讨论】:

    标签: oracle alter


    【解决方案1】:

    Oracle 中的NUMBER 没有内在的“格式”,即它的内部表示不依赖于它的精度或规模。例如,NUMBER 123456 如果声明为NUMBER(9,2)INTEGER,则其内部表示方式相同:

    SQL> SELECT dump(CAST(123456 AS INTEGER)) int,
      2         dump(CAST(123456 AS NUMBER(9,2))) num
      3    FROM dual;
    
    INT                       NUM
    ------------------------- --------------------
    Typ=2 Len=4: 195,13,35,57 Typ=2 Len=4: 195,13,35,57                    
    

    INTEGER(7)NUMBER(9,2) 在列中的唯一区别是INTEGER(7) 具有更强的检查约束。两列将以完全相同的方式在内部表示数据。

    这就是为什么您可以提高非空列的列的精度没有问题,ALTER TABLE 只会修改元数据(字典表),因此应该立即使用很少重做。

    SQL> create table test (id number(7));
    
    Table created.
    
    SQL> insert into test values (123456);
    
    1 row created.
    
    SQL> alter table test modify (id number(9,2));
    
    Table altered.
    
    SQL> select * from test;
    
            ID
    ----------
        123456
    

    【讨论】:

      【解决方案2】:

      您将无法修改现有列的数据类型:

      ORA-01439: 要修改的列必须为空才能更改数据类型

      因此,如果你想拥有浮点列,你需要创建一个,用你的整数列的数据更新它,然后删除整数列。 DDL 很快,但是更新 1M 行需要时间。您可能希望将其限制为 50000 行并在每次更新后提交,这样会更快:

      UPDATE MyTable SET NewFloatField = OldINtegerField WHERE NewFloatField IS NULL AND rownum

      您可以采用另一种方式在应用程序中更改 SQL,并在插入数据时乘以 100,在检索数据时除以 100。但是,我会修改数据库以使数据来自一个来源,而无需在插入或读取数据的所有地方进行解释。

      【讨论】:

      • 我不同意,您可以修改列,只要您提高其精度。从NUMBER(9)NUMBER(11,2) 始终是可能的。逻辑上等价于从VARCHAR2(9)VARCHAR2(11)
      猜你喜欢
      • 2013-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多