Saya punya pertanyaan tentang ALTER TABLE
perintah di atas meja yang sangat besar (hampir 30 juta baris). Salah satu kolomnya adalah a varchar(255)
dan saya ingin mengubah ukurannya menjadi a varchar(40)
. Pada dasarnya, saya ingin mengubah kolom saya dengan menjalankan perintah berikut:
ALTER TABLE mytable ALTER COLUMN mycolumn TYPE varchar(40);
Saya tidak punya masalah jika prosesnya sangat lama tetapi sepertinya meja saya tidak lagi dapat dibaca selama perintah ALTER TABLE. Apakah ada cara yang lebih pintar? Mungkin menambahkan kolom baru, menyalin nilai dari kolom lama, menjatuhkan kolom lama dan akhirnya mengganti nama yang baru?
Petunjuk apa pun akan sangat dihargai! Terima kasih sebelumnya,
Catatan: Saya menggunakan PostgreSQL 9.0.
postgresql
varchar
alter-table
Labynocle
sumber
sumber
resizing
tidak akan membuat meja menempati ruang lebih sedikit?varchar(255)
kepada PostgreSQL maka itu tidak akan mengalokasikan 255 byte untuk nilai yang panjang sebenarnya adalah 40 byte. Ini akan mengalokasikan 40 byte (ditambah beberapa overhead internal). Satu-satunya hal yang akanbe changed by the
ALTER TABLE` adalah jumlah byte maksimum yang dapat Anda simpan di kolom itu tanpa mendapatkan kesalahan dari PG.Jawaban:
Ada deskripsi tentang bagaimana melakukan ini di Ubah ukuran kolom dalam tabel PostgreSQL tanpa mengubah data . Anda harus meretas data katalog basis data. Satu-satunya cara untuk melakukan ini secara resmi adalah dengan ALTER TABLE, dan seperti yang Anda perhatikan bahwa perubahan akan mengunci dan menulis ulang seluruh tabel saat sedang berjalan.
Pastikan Anda membaca bagian Jenis Karakter dari dokumen sebelum mengubah ini. Segala macam kasus aneh yang harus diperhatikan di sini. Pemeriksaan panjang dilakukan ketika nilai disimpan ke dalam baris. Jika Anda meretas batas bawah di sana, itu tidak akan mengurangi ukuran nilai yang ada sama sekali. Anda sebaiknya melakukan pemindaian pada seluruh tabel untuk mencari baris yang panjang bidangnya> 40 karakter setelah melakukan perubahan. Anda harus mencari cara untuk memotongnya secara manual - jadi Anda kembali beberapa kunci hanya pada yang kebesaran - karena jika seseorang mencoba memperbarui apa pun di baris itu akan menolaknya terlalu besar sekarang, pada titik ia pergi untuk menyimpan versi baris baru. Hilaritas terjadi untuk pengguna.
VARCHAR adalah tipe mengerikan yang ada di PostgreSQL hanya untuk memenuhi bagian mengerikan yang terkait dengan standar SQL. Jika Anda tidak peduli dengan kompatibilitas multi-basis data, pertimbangkan untuk menyimpan data Anda sebagai TEXT dan tambahkan batasan untuk membatasi panjangnya. Kendala yang bisa Anda ubah tanpa masalah penguncian / penulisan tabel ini, dan mereka bisa melakukan pemeriksaan integritas lebih dari sekadar pemeriksaan panjang yang lemah.
sumber
Di PostgreSQL 9.1 ada cara yang lebih mudah
http://www.postgresql.org/message-id/[email protected]
sumber
Ok, saya mungkin terlambat ke pesta, TAPI ...
TIDAK PERLU MENGUBAH KOLOM DALAM KASUS ANDA!
Postgres, tidak seperti beberapa database lain, cukup pintar untuk hanya menggunakan ruang yang cukup agar sesuai dengan string (bahkan menggunakan kompresi untuk string yang lebih lama), jadi bahkan jika kolom Anda dinyatakan sebagai VARCHAR (255) - jika Anda menyimpan string 40-karakter dalam kolom, penggunaan ruang akan menjadi 40 byte + 1 byte overhead.
( http://www.postgresql.org/docs/9.0/interactive/datatype-character.html )
Spesifikasi ukuran dalam VARCHAR hanya digunakan untuk memeriksa ukuran nilai yang dimasukkan, itu tidak mempengaruhi tata letak disk. Faktanya, bidang VARCHAR dan TEXT disimpan dengan cara yang sama di Postgres .
sumber
Saya menghadapi masalah yang sama mencoba untuk memotong VARCHAR dari 32 menjadi 8 dan mendapatkan
ERROR: value too long for type character varying(8)
. Saya ingin tetap sedekat mungkin dengan SQL karena saya menggunakan struktur mirip JPA yang dibuat sendiri sehingga kita mungkin harus beralih ke DBMS yang berbeda sesuai dengan pilihan pelanggan (PostgreSQL menjadi yang default). Oleh karena itu, saya tidak ingin menggunakan trik mengubah tabel Sistem.Saya berakhir menggunakan
USING
pernyataan diALTER TABLE
:Seperti dicatat oleh @raylu,
ALTER
memperoleh kunci eksklusif di atas meja sehingga semua operasi lainnya akan tertunda hingga selesai.sumber
ALTER
memperoleh kunci eksklusif di atas meja dan mencegah semua operasi lainnyaMenambahkan kolom baru dan mengganti yang baru dengan yang lama berfungsi untuk saya, di redshift postgresql, lihat tautan ini untuk lebih jelasnya https://gist.github.com/mmasashi/7107430
sumber
Ini cache halaman yang dijelaskan oleh Greg Smith. Jika itu mati juga, pernyataan alter terlihat seperti ini:
Di mana tabel Anda adalah TABLE1, kolomnya adalah COL1 dan Anda ingin mengaturnya menjadi 35 karakter (+4 diperlukan untuk tujuan warisan sesuai dengan tautan, mungkin overhead yang dirujuk oleh AH dalam komentar).
sumber
jika Anda memasukkan alter ke dalam transaksi, tabel tidak boleh dikunci:
ini bekerja untuk saya dengan sangat cepat, beberapa detik di atas meja dengan lebih dari 400 ribu baris.
sumber
ALTER
pernyataan? Tidak.COMMIT
. Pembungkus hanya masuk akal jika Anda ingin memasukkan lebih banyak perintah ke dalam transaksi yang sama.Saya telah menemukan cara yang sangat mudah untuk mengubah ukuran yaitu penjelasan @ Ukuran (min = 1, maks = 50) yang merupakan bagian dari "import javax.validation.constraints" yaitu "import javax.validation.constraints.Size;"
sumber
Coba jalankan tabel ubah berikut:
sumber