【问题标题】:Move a column to a new table in ORACLE在 ORACLE 中将列移动到新表
【发布时间】:2020-04-16 23:06:46
【问题描述】:

我有很多用户的下表:

USERS
-----
id
name
lastname
cv

我想将该表划分为:

USERS
-----
id
name
lastname

USER_CVS
--------
id
user_id
cv

在 ORACLE 中,我的方法是:

  1. 创建 USER_CVS 表
  2. 使用 INSERT INTRO USER_CVS SELECT ... FROM USERS 插入数据
  3. 从 USERS 中删除 cv 列

但是,有两个问题:

  • 在2.数据库中的数据量翻倍,我没有那么多空间。
  • 复制cvs需要很长时间

还有其他方法来划分这个表吗?

【问题讨论】:

  • 我所做的技巧是添加一个额外的列migrated number(1),其值为零(false)。然后,我一次迁移一千个(或任何其他大小)的子集:迁移、标记、删除、重复。这样我就不会用完空间。
  • 在查看技术解决方案之前,我会问您为什么要这样做?首先,每个表都有一定数量的固定和成比例的开销,因此将 x 量的数据分布在两个表中占用更多空间。其次,更重要的是,将其拆分为两个表如何影响正确规范化的数据设计?
  • 规范化数据并不意味着不必要地将一个表拆分为多个表并复制数据。如果这是一个生产级设计,那么您应该回到您的绘图板并考虑设计。

标签: sql database oracle


【解决方案1】:

您可以创建 TEMP 表并相应地移动列。

像这样:

--Create temp table
CREATE TABLE USERS_TEMP
AS
SELECT ID, NAME, LASTNAME FROM USERS;

--Rename ID to USER_ID in original table
ALTER TABLE USERS RENAME COLUMN ID TO USER_ID;

--Add ID column in original table
ALTER TABLE USERS ADD ID NUMBER;

--Drop name column from original table
ALTER TABLE USERS DROP COLUMN NAME; 

--Drop lastname column from original table
ALTER TABLE USERS DROP COLUMN LASTNAME;

--rename original table to USER_CVS
ALTER TABLE USERS RENAME TO USER_CVS;

--rename temp table to USERS_TEMP
ALTER TABLE USERS_TEMP RENAME TO USERS;

--use some sequence to update the ID column in USER_CVS
UPDATE USER_CVS SET ID = SEQUENCE.NEXTVAL;

【讨论】:

  • 谢谢,这是个好主意!
【解决方案2】:

一种方法是在源表中将数据拆分成块,然后在目标表中插入第一个块,然后在源表中将该块更新为空。

在所有块都被移动之后,然后将列删除到源表中。

创建块的方法在这个question中给出

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多