Saya memiliki meja dengan lebih dari jutaan baris. Saya perlu mengatur ulang urutan dan menetapkan kembali kolom id dengan nilai baru (1, 2, 3, 4 ... dll ...). Apakah ada cara mudah untuk melakukan itu?
postgresql
sequence
sennin
sumber
sumber
id
ada tidak mulai dari 1. Jadi urutannya ternyata sebagai berikut: 150, 151 ..., 300, 1, 2 ... Dan itu akan menyebabkan kesalahan id duplikat pada akhirnya saya kira, jika saya tidak menomori ulang id. Selain itu, pesan berdasarkanid
umumnya lebih baik daripada memesan berdasarkancreated_at
. Dan inilah yang berhasil untuk saya .Jawaban:
Jika Anda tidak ingin mempertahankan urutan id, Anda bisa
Saya ragu ada cara mudah untuk melakukannya dalam urutan pilihan Anda tanpa membuat ulang seluruh tabel.
sumber
ALTER SEQUENCE seq RESTART WITH 1;
?SELECT setval('seq', 1, FALSE)
harus melakukan hal yang sama (di sini, argumen ketiga, SALAH, melakukan keajaiban, karena itu menunjukkan bahwanextval
harus 1 bukan 2)Dengan PostgreSQL 8.4 atau yang lebih baru, tidak perlu
WITH 1
lagi menentukan . Nilai awal yang direkam olehCREATE SEQUENCE
atau set terakhir olehALTER SEQUENCE START WITH
akan digunakan (kemungkinan besar ini adalah 1).Setel ulang urutan:
Kemudian perbarui kolom ID tabel:
Sumber: Dokumen PostgreSQL
sumber
Setel ulang urutan:
Memperbarui catatan saat ini:
sumber
serial
danCREATE SEQUENCE
adalah 1!)Kedua solusi yang diberikan tidak berhasil untuk saya;
setval('seq', 1)
memulai penomoran dengan 2, danALTER SEQUENCE seq START 1
memulai penomoran dengan 2 juga, karena seq.is_called adalah true (Postgres versi 9.0.4)Solusi yang berhasil untuk saya adalah:
sumber
Hanya untuk menyederhanakan dan memperjelas penggunaan ALTER SEQUENCE dan SELECT setval untuk mengatur ulang urutan:
setara dengan
Salah satu pernyataan dapat digunakan untuk mengatur ulang urutan dan Anda bisa mendapatkan nilai berikutnya dengan nextval ('sequence_name') seperti yang dinyatakan di sini juga:
sumber
Cara terbaik untuk menyetel ulang urutan untuk memulai kembali dengan nomor 1 adalah dengan menjalankan yang berikut ini:
Jadi, misalnya untuk tabel users akan menjadi:
sumber
Untuk mempertahankan urutan baris:
sumber
FYI: Jika Anda perlu menentukan nilai awal baru antara rentang ID (256 - 10000000 misalnya):
sumber
Hanya mengatur ulang urutan dan memperbarui semua baris dapat menyebabkan kesalahan id duplikat. Dalam banyak kasus, Anda harus memperbarui semua baris dua kali. Pertama dengan id yang lebih tinggi untuk menghindari duplikat, lalu dengan id yang Anda inginkan.
Harap hindari untuk menambahkan jumlah tetap ke semua id (seperti yang direkomendasikan di komentar lain). Apa yang terjadi jika Anda memiliki lebih banyak baris daripada jumlah tetap ini? Dengan asumsi nilai berikutnya dari urutan lebih tinggi dari semua id dari baris yang ada (Anda hanya ingin mengisi celah), saya akan melakukannya seperti:
sumber
Dalam kasus saya, saya mencapai ini dengan:
Dimana meja saya diberi nama table
sumber
Terinspirasi oleh jawaban lain di sini, saya membuat fungsi SQL untuk melakukan migrasi urutan. Fungsi ini memindahkan urutan kunci primer ke urutan baru yang berdekatan yang dimulai dengan nilai apa pun (> = 1) baik di dalam maupun di luar rentang urutan yang ada.
Saya menjelaskan di sini bagaimana saya menggunakan fungsi ini dalam migrasi dua database dengan skema yang sama tetapi nilai berbeda ke dalam satu database.
Pertama, fungsinya (yang mencetak perintah SQL yang dihasilkan sehingga jelas apa yang sebenarnya terjadi):
Fungsi tersebut
migrate_pkey_sequence
mengambil argumen berikut:arg_table
: nama tabel (mis.'example'
)arg_column
: nama kolom kunci utama (mis'id'
)arg_sequence
: nama urutan (misalnya'example_id_seq'
)arg_next_value
: nilai berikutnya untuk kolom setelah migrasiItu melakukan operasi berikut:
nextval('example_id_seq')
berikutmax(id)
dan urutannya dimulai dengan 1. Ini juga menangani kasus di manaarg_next_value > max(id)
.arg_next_value
. Urutan nilai kunci dipertahankan tetapi lubang pada kisaran tidak dipertahankan.Untuk mendemonstrasikan, kami menggunakan urutan dan tabel yang ditentukan sebagai berikut (misalnya menggunakan
psql
):Kemudian, kami memasukkan beberapa nilai (mulai, misalnya, pada 3):
Terakhir, kami memigrasi
example.id
nilai untuk memulai dengan 1.Hasil:
sumber
Bahkan kolom auto-increment bukan PK (dalam contoh ini disebut seq - aka sequence) Anda dapat mencapainya dengan pemicu:
DROP TABLE JIKA ADA devops_guide CASCADE;
sumber
Jika Anda menggunakan pgAdmin3, perluas 'Sequences', klik kanan pada urutan, buka 'Properties,' dan di tab 'Definition' ubah 'Nilai saat ini' ke nilai apa pun yang Anda inginkan. Tidak perlu kueri.
sumber