Ändern Sie den Spaltendatentyp in Amazon Redshift

84

Wie ändere ich den Spaltendatentyp in der Amazon Redshift-Datenbank?

Ich kann den Spaltendatentyp in Redshift nicht ändern. Gibt es eine Möglichkeit, den Datentyp in Amazon Redshift zu ändern?

user1485267
quelle
6
"Tabelle als Auswahl erstellen ..." Und entwerfen Sie Ihre neue Tabelle mit dem besseren Spaltentyp.
Guy

Antworten:

133

Wie in der Dokumentation zu ALTER TABLE angegeben , können Sie die Länge von VARCHARSpalten mithilfe von ändern

ALTER TABLE table_name
{
    ALTER COLUMN column_name TYPE new_data_type 
}

Bei anderen Spaltentypen kann ich mir nur vorstellen, eine neue Spalte mit einem korrekten Datentyp hinzuzufügen, dann alle Daten aus der alten Spalte in eine neue einzufügen und schließlich die alte Spalte zu löschen.

Verwenden Sie einen ähnlichen Code:

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;

Es wird eine Schemaänderung geben - die neu hinzugefügte Spalte wird die letzte in einer Tabelle sein (dies kann ein Problem mit der COPYAnweisung sein, denken Sie daran - Sie können eine Spaltenreihenfolge mit definieren COPY).

Tomasz Tybulewicz
quelle
4
ALTER oder eine DDL-Anweisung wird sofort festgeschrieben, unabhängig davon, ob sie in eine Transaktion eingebunden ist oder nicht.
Raniendu Singh
@RanienduSingh Einige Datenbanken unterstützen transaktionale DDL-Anweisungen. Ich habe keine maßgebliche Liste gefunden, aber die meisten DDL-Anweisungen in Redshift scheinen in einer Transaktion zu funktionieren. Ich denke jedoch, dass die Neuordnung der Vorgänge ähnlich dem hier beschriebenen Ansatz (Umbenennen, Hinzufügen, Aktualisieren, Löschen
Matt Good
1
Es ist erwähnenswert, dass es jetzt möglich ist, die Größe der varchar-Spalten zu erhöhen - siehe die Antwort von user0000 unten und den Link zu den Dokumenten ( docs.aws.amazon.com/redshift/latest/dg/r_ALTER_TABLE.html )
willis
1
@Tomasz Tybulewicz Würden Sie bitte Ihre Antwort einschließlich der Antwort von user0000 aktualisieren? Ihre Antwort war zu der Zeit richtig, aber ich wurde irregeführt. Zum Glück habe ich auch die Antwort von
user0000
43

um die von Tomasz erwähnte Schemaänderung zu vermeiden:

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;
Wolli
quelle
1
Dies ist auch die Methode, die wir verwenden, um eine Fehlausrichtung der Kopieranweisung zu vermeiden.
smb
1
Beachten Sie, dass alle Ansichten, die zur Auswahl aus alten Tabellen verwendet wurden, weiterhin auf alte Tabellen verweisen. Die drop tableAbfrage zeigt den Abhängigkeitsfehler an, der umgangen werden kann, aber nicht umgangen werden sollte.
1
Danke dafür, es war wirklich hilfreich. Ich habe es für eine Tabelle mit 31 Millionen Zeilen verwendet und es dauerte nur 3 Minuten mit dem Typ dc1.large. Toll! Ich habe auch eine etwas einfachere Form verwendet:INSERT INTO <TABLE_NAME> SELECT * FROM <TABLE_NAME>_OLD;
Tom
Die Kapselung mit TRANSACTION ist sehr wichtig
louis_guitton
15

(Letzte Aktualisierung) Es ist möglich, den Typ für Varchar-Spalten in Redshift zu ändern.

ALTER COLUMN column_name TYPE new_data_type

Beispiel:

CREATE TABLE t1 (c1 varchar(100))

ALTER TABLE t1 ALTER COLUMN c1 TYPE varchar(200)

Hier ist die Dokumentation Link

user0000
quelle
Das funktioniert perfekt. Ein netter Einzeiler, der das Schema überhaupt nicht ändert, sondern den Datentyp aktualisiert. Dies sollte die neue aktualisierte Antwort sein!
Timothy Mcwilliams
8

Wenn Sie die Spaltenreihenfolge nicht ändern möchten , können Sie eine temporäre Tabelle erstellen, die neue Tabelle mit der gewünschten Größe löschen und erstellen und dann die Daten erneut zusammenfassen.

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;

Das einzige Problem beim Neuerstellen der Tabelle besteht darin, dass Sie erneut Berechtigungen erteilen müssen. Wenn die Tabelle zu groß ist, dauert dies einige Zeit.

Franzi
quelle
1
Dies ist der vorhandenen Antwort von Wolli ziemlich ähnlich, die alten Tabellendaten umzubenennen und dann in das neue Schema zu kopieren. Beide behalten die Spaltenreihenfolge bei, aber diese Lösung mit einer temporären Tabelle erfordert ein zweimaliges Kopieren der Daten. Einmal zum Kopieren in die temporäre Tabelle und einmal zum Zurückkopieren in die neue Tabelle. Das Umbenennen der Tabelle sollte schneller erfolgen, indem nur eine Kopie ausgeführt wird.
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;
Anand Kumar
quelle
3

Da Redshift eine spaltbare Datenbank ist, können Sie den Datentyp nicht direkt ändern. Im Folgenden finden Sie jedoch einen Ansatz, mit dem die Spaltenreihenfolge geändert wird.

Schritte -

1.Alter-Tabelle Hinzufügen einer neuen Spalte zur Tabelle 2. Aktualisieren Sie den Wert der neuen Spalte mit dem Wert der alten Spalte 3.Alter-Tabelle zum Löschen der alten Spalte 4. Alter-Tabelle zum Umbenennen der Spalte in die alte Spalte

Wenn Sie die Reihenfolge der Spalten nicht ändern möchten, ist die Lösung zu

1.Erstellen Sie eine temporäre Tabelle mit einem neuen Spaltennamen

  1. Kopieren Sie Daten von der alten Tabelle in die neue Tabelle.

  2. alten Tisch fallen lassen

  3. Benennen Sie die Newtable in Oldtable um

  4. Eine wichtige Sache ist, eine neue Tabelle mit dem Befehl like zu erstellen, anstatt einfach zu erstellen.

Rama krishna
quelle
2

Diese Methode funktioniert zum Konvertieren einer (großen) int-Spalte in einen 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;
comfytoday
quelle
-2

Für die Aktualisierung derselben Spalte in Rotverschiebung würde dies gut funktionieren

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

Sie können mehrere Klauseln verwenden, indem Sie und verwenden, um Verwirrung für SQL zu vermeiden

Prost!!

Achin Saharawat
quelle