Mam pytanie odnośnie ALTER TABLE
polecenia na naprawdę dużym stole (prawie 30 milionów wierszy). Jedna z jego kolumn to a varchar(255)
i chciałbym zmienić jej rozmiar na a varchar(40)
. Zasadniczo chciałbym zmienić moją kolumnę, uruchamiając następujące polecenie:
ALTER TABLE mytable ALTER COLUMN mycolumn TYPE varchar(40);
Nie mam problemu, jeśli proces jest bardzo długi, ale wydaje się, że moja tabela nie jest bardziej czytelna podczas polecenia ALTER TABLE. Czy jest mądrzejszy sposób? Może dodać nową kolumnę, skopiować wartości ze starej kolumny, usunąć starą kolumnę i na koniec zmienić nazwę nowej?
Każda wskazówka będzie bardzo mile widziana! Z góry dziękuję,
Uwaga: używam PostgreSQL 9.0.
postgresql
varchar
alter-table
Labynocle
źródło
źródło
resizing
nie sprawi, że stół będzie zajmował mniej miejsca?varchar(255)
PostgreSQL nie przydzieli 255 bajtów wartości, której rzeczywista długość wynosi 40 bajtów. Przydzieli 40 bajtów (plus trochę narzutu wewnętrznego). Jedyną rzeczą, która zmienibe changed by the
opcję ALTER TABLE, jest maksymalna liczba bajtów, które możesz przechowywać w tej kolumnie bez otrzymywania błędu od PG.Odpowiedzi:
Opis tego, jak to zrobić, znajduje się w sekcji Zmień rozmiar kolumny w tabeli PostgreSQL bez zmiany danych . Musisz włamać się do danych katalogu bazy danych. Jedynym sposobem, aby to zrobić oficjalnie, jest ALTER TABLE, a jak zauważyłeś, zmiana spowoduje zablokowanie i przepisanie całej tabeli podczas jej działania.
Upewnij się, że przeczytałeś sekcję Typy znaków w dokumentach przed zmianą tego. Różne dziwne przypadki, o których należy tutaj pamiętać. Kontrola długości jest wykonywana, gdy wartości są przechowywane w wierszach. Jeśli zhakujesz tam dolny limit, w ogóle nie zmniejszy to rozmiaru istniejących wartości. Po dokonaniu zmiany warto przeskanować całą tabelę, szukając wierszy, w których długość pola przekracza 40 znaków. Będziesz musiał wymyślić, jak skrócić je ręcznie - więc wróciłeś do niektórych blokad tylko tych dużych rozmiarów - ponieważ jeśli ktoś spróbuje zaktualizować cokolwiek w tym wierszu, odrzuci to teraz jako zbyt duże, w tym momencie przechowuje nową wersję wiersza. Dla użytkownika nastaje wesołość.
VARCHAR to okropny typ, który istnieje w PostgreSQL tylko po to, aby zachować zgodność z powiązaną z nim straszną częścią standardu SQL. Jeśli nie zależy Ci na kompatybilności z wieloma bazami danych, rozważ przechowywanie danych jako TEKST i dodaj ograniczenie, aby ograniczyć jego długość. Ograniczenia, które można zmieniać bez problemu z blokowaniem / przepisywaniem tabeli, i mogą wykonywać więcej sprawdzania integralności niż tylko sprawdzanie słabej długości.
źródło
W PostgreSQL 9.1 jest prostszy sposób
http://www.postgresql.org/message-id/[email protected]
źródło
Ok, pewnie spóźniłem się na imprezę, ALE ...
NIE MA POTRZEBY ZMIENIANIA KOLUMNY W TWOIM PRZYPADKU!
Postgres, w przeciwieństwie do niektórych innych baz danych, jest na tyle inteligentny, że używa tylko wystarczającej ilości miejsca, aby dopasować ciąg (nawet używając kompresji dla dłuższych ciągów), więc nawet jeśli twoja kolumna jest zadeklarowana jako VARCHAR (255) - jeśli przechowujesz 40-znakowe ciągi w w kolumnie, użycie miejsca wyniesie 40 bajtów + 1 bajt narzutu.
( http://www.postgresql.org/docs/9.0/interactive/datatype-character.html )
Specyfikacja rozmiaru w VARCHAR służy tylko do sprawdzania rozmiaru wstawianych wartości, nie wpływa na układ dysku. W rzeczywistości pola VARCHAR i TEXT są przechowywane w ten sam sposób w Postgres .
źródło
Miałem ten sam problem, próbując skrócić VARCHAR z 32 do 8 i uzyskać rozszerzenie
ERROR: value too long for type character varying(8)
. Chcę pozostać jak najbliżej SQL, ponieważ używam samodzielnie wykonanej struktury podobnej do JPA, która może być konieczna do przełączenia się na inny DBMS zgodnie z wyborami klienta (domyślnie PostgreSQL). Dlatego nie chcę używać sztuczki polegającej na zmienianiu tabel systemowych.Skończyłem używając
USING
oświadczenia wALTER TABLE
:Jak zauważył @raylu,
ALTER
uzyskuje wyłączną blokadę stołu, więc wszystkie inne operacje będą opóźnione do zakończenia.źródło
ALTER
nabywa wyłączną blokadę na stole i zapobiega wszystkie inne operacjeDodając nową kolumnę i zastępując nową starą, pracowałem dla mnie, na redshift postgresql, zapoznaj się z tym linkiem, aby uzyskać więcej informacji https://gist.github.com/mmasashi/7107430
źródło
Oto pamięć podręczna strony opisanej przez Grega Smitha. W przypadku, gdy to również umrze, oświadczenie alter wygląda następująco:
Jeśli twoja tabela to TABELA1, kolumna to COL1 i chcesz ustawić ją na 35 znaków (+4 jest potrzebne do starszych celów zgodnie z linkiem, prawdopodobnie narzut, do którego odnosi się AH w komentarzach).
źródło
jeśli umieścisz zmianę w transakcji, tabela nie powinna być blokowana:
to zadziałało dla mnie błyskawicznie, kilka sekund na stole z ponad 400 tysiącami wierszy.
źródło
ALTER
instrukcji? Tak nie jest.COMMIT
. Opakowanie ma sens tylko wtedy, gdy chcesz umieścić więcej poleceń w tej samej transakcji.Znalazłem bardzo łatwy sposób na zmianę rozmiaru, tj. Adnotację @Size (min = 1, max = 50), która jest częścią "importu javax.validation.constraints" tj. "Importu javax.validation.constraints.Size;"
źródło
Spróbuj uruchomić następującą tabelę zmian:
źródło