Modifica il tipo di dati della colonna in Amazon Redshift


85

Come modificare il tipo di dati della colonna nel database di Amazon Redshift?

Non sono in grado di modificare il tipo di dati della colonna in Redshift; c'è un modo per modificare il tipo di dati in Amazon Redshift?


6
"Crea tabella come selezione ..." e progetta la tua nuova tabella con il tipo di colonna migliore.
Guy

Risposte:


137

Come indicato nella documentazione di ALTER TABLE , è possibile modificare la lunghezza delle VARCHARcolonne utilizzando

ALTER TABLE table_name
{
    ALTER COLUMN column_name TYPE new_data_type 
}

Per altri tipi di colonna tutto ciò a cui riesco a pensare è aggiungere una nuova colonna con un tipo di dati corretto, quindi inserire tutti i dati dalla vecchia colonna a una nuova e infine rilasciare la vecchia colonna.

Usa un codice simile a quello:

ALTER TABLE t1 ADD COLUMN new_column ___correct_column_type___;
UPDATE t1 SET new_column = column;
ALTER TABLE t1 DROP COLUMN column;
ALTER TABLE t1 RENAME COLUMN new_column TO column;

Ci sarà una modifica dello schema: la colonna appena aggiunta sarà l'ultima in una tabella (potrebbe essere un problema con l' COPYistruzione, tienilo a mente: puoi definire un ordine di colonna con COPY)


4
ALTER o per quella materia qualsiasi istruzione DDL si impegna immediatamente a prescindere dal tempo che sia avvolto in una transazione o meno.
Raniendu Singh

@RanienduSingh alcuni database supportano le istruzioni DDL transazionali. Non ho trovato un elenco autorevole, ma la maggior parte delle istruzioni DDL in Redshift sembra funzionare in una transazione. Tuttavia, penso che riordinare le operazioni simili all'approccio qui descritto (rinomina, aggiungi, aggiorna, rilascia) possa essere più robusto: simple.com/engineering/safe-migrations-with-redshift
Matt Good

1
Vale la pena notare che ora è possibile aumentare la dimensione delle colonne varchar - vedere la risposta di user0000 di seguito e il collegamento ai documenti ( docs.aws.amazon.com/redshift/latest/dg/r_ALTER_TABLE.html )
willis

1
@Tomasz Tybulewicz, aggiorni la tua risposta includendo la risposta di user0000? La tua risposta era corretta al momento, ma sono stato fuorviato. Fortunatamente ho letto anche la risposta di
user0000

43

per evitare il cambio di schema menzionato da Tomasz:

BEGIN TRANSACTION;

ALTER TABLE <TABLE_NAME> RENAME TO <TABLE_NAME>_OLD;
CREATE TABLE <TABLE_NAME> ( <NEW_COLUMN_DEFINITION> );
INSERT INTO <TABLE_NAME> (<NEW_COLUMN_DEFINITION>)
SELECT <COLUMNS>
FROM <TABLE_NAME>_OLD;
DROP TABLE <TABLE_NAME>_OLD;

END TRANSACTION;

1
Questo è il metodo che utilizziamo anche per evitare il disallineamento dell'istruzione di copia.
smb

1
Tieni presente che tutte le visualizzazioni che utilizzavano per selezionare dalla vecchia tabella continuano a puntare alla vecchia tabella. La drop tablequery mostrerà l'errore di dipendenza che può essere ma non dovrebbe essere ignorato.

1
Grazie per questo, è stato davvero utile. L'ho usato su una tabella con 31 milioni di righe e ci sono voluti solo 3 minuti usando il tipo dc1.large. Grande! Ho anche usato una forma leggermente più semplice:INSERT INTO <TABLE_NAME> SELECT * FROM <TABLE_NAME>_OLD;
Tom

L'incapsulamento con TRANSACTION è molto importante
louis_guitton

16

(Aggiornamento recente) È possibile modificare il tipo per le colonne varchar in Redshift.

ALTER COLUMN column_name TYPE new_data_type

Esempio:

CREATE TABLE t1 (c1 varchar(100))

ALTER TABLE t1 ALTER COLUMN c1 TYPE varchar(200)

Ecco il link alla documentazione


Funziona perfettamente. Un bel liner che non cambierà affatto lo schema ma aggiornerà il tipo di dati. Questa dovrebbe essere la nuova risposta aggiornata!
Timothy Mcwilliams

8

Se non desideri modificare l'ordine delle colonne , un'opzione creerà una tabella temporanea, rilascia e crea quella nuova con le dimensioni desiderate e quindi raggruppa nuovamente i dati.

CREATE TEMP TABLE temp_table AS SELECT * FROM original_table;
DROP TABLE original_table;
CREATE TABLE original_table ...
INSERT INTO original_table SELECT * FROM temp_table;

L'unico problema nel ricreare la tabella è che dovrai concedere nuovamente i permessi e se la tabella è troppo grande ci vorrà un po 'di tempo.


1
Questo è abbastanza simile alla risposta esistente di Wolli per rinominare e quindi copiare i dati della vecchia tabella nel nuovo schema. Entrambi manterranno l'ordine delle colonne, ma questa soluzione con una tabella temporanea richiede la copia dei dati due volte. Una volta per copiare nella tabella temporanea e un'altra per copiare di nuovo nella nuova tabella. La ridenominazione della tabella dovrebbe essere più veloce eseguendo solo una copia.
Matt Good

4
ALTER TABLE publisher_catalogs ADD COLUMN new_version integer;

update publisher_catalogs set new_version = CAST(version AS integer);
ALTER TABLE publisher_catalogs DROP COLUMN version RESTRICT;
ALTER TABLE publisher_catalogs RENAME new_version to version;

3

Redshift essendo un database colonnare non ti consente di modificare direttamente il tipo di dati, tuttavia di seguito è un approccio che cambierà l'ordine delle colonne.

Passi -

1.Alter table aggiungi newcolumn alla tabella 2.Aggiorna il valore newcolumn con il valore oldcolumn 3.Alter table per eliminare la oldcolumn 4.alter table per rinominare la columnn in oldcolumn

Se non vuoi modificare l'ordine delle colonne, la soluzione sarebbe

1.crea una tabella temporanea con un nuovo nome di colonna

  1. copia i dati dalla vecchia tabella alla nuova tabella.

  2. lascia cadere il vecchio tavolo

  3. rinominare la newtable in oldtable

  4. Una cosa importante è creare una nuova tabella usando il comando like invece della semplice creazione.


2

Questo metodo funziona per convertire una (grande) colonna int in un varchar

-- Create a backup of the original table
create table original_table_backup as select * from original_table;

-- Drop the original table, and then recreate with new desired data types
drop table original_table;

create table original_table (
  col1 bigint,
  col2 varchar(20) -- changed from bigint
);

-- insert original entries back into the new table
insert into original_table select * from original_table_backup;

-- cleanup
drop original_table_backup;

0

SCARICARE e COPIARE con la strategia di ridenominazione della tabella dovrebbe essere il modo più efficiente per eseguire questa operazione se è importante mantenere la struttura della tabella (ordine delle righe).

Ecco un esempio che si aggiunge a questa risposta.

BEGIN TRANSACTION;

ALTER TABLE <TABLE_NAME> RENAME TO <TABLE_NAME>_OLD;
CREATE TABLE <TABLE_NAME> ( <NEW_COLUMN_DEFINITION> );
UNLOAD ('select * from <TABLE_NAME>_OLD') TO 's3://bucket/key/unload_' manifest;
COPY <TABLE_NAME> FROM 's3://bucket/key/unload_manifest'manifest;

END TRANSACTION;

-2

per aggiornare la stessa colonna in redshift questo funzionerebbe bene

UPDATE table_name 
SET column_name = 'new_value' WHERE column_name = 'old_value'

puoi avere più clausole in cui usando e, in modo da rimuovere qualsiasi confusione per sql

Saluti!!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.