Mengubah kolom identitas dari INT ke BIGINT

9

Saya memiliki tabel dengan kolom identitas yang juga merupakan kunci utama. Saat ini, ia memiliki 50 juta baris, dengan nilai tertinggi dari kolom identitas berada di 148.921.803. Tabel memiliki banyak DELETEdan INSERTSdilakukan di atasnya, maka nilainya tinggi.

Kami ingin mengubah tipe data dari INTmenjadi BIGINTuntuk mempersiapkan penambahan lebih banyak baris. Perhatikan bahwa, tidak ada referensi ke kolom PK.

Apa cara terbaik untuk melakukan ini, dengan downtime minimal? Saya punya dua opsi.

  1. Jatuhkan PK dan ubah kolom; atau
  2. Metode copy-drop-rename, seperti dijelaskan di sini :
Felix Pamittan
sumber

Jawaban:

7

Karena ada kunci utama yang didefinisikan pada kolom identitas, Anda tidak akan dapat langsung mengubah kolom ini.

Kedua pendekatan yang telah Anda sebutkan dalam pertanyaan Anda dapat digunakan dan waktu henti bergantung pada kinerja server Anda dan jumlah baris yang berada di tabel itu.

  1. Jatuhkan PK dan ubah kolom; atau

Jatuhkan dulu PK

/****** Object: DROP Index [PK_DatabaseLog_DatabaseLogID]******/

ALTER TABLE [dbo].[TableName] DROP CONSTRAINT [PK_TableName_ID]
GO

Alter Column

ALTER TABLE [dbo].[TableName] ALTER COLUMN [dbo.ID] BIGINT

Tambahkan kunci Utama

/****** Object: ADD Index [PK_DatabaseLog_DatabaseLogID]******/
ALTER TABLE [dbo].[TableName] ADD  CONSTRAINT [PK_TableName_ID] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)

Pendekatan ini biasanya tidak memakan banyak waktu. Di lingkungan saya, dibutuhkan beberapa detik di atas meja besar yang memiliki lebih dari 5 juta baris.

  1. Metode copy-drop-rename, seperti yang dijelaskan

Anda dapat menggunakan pendekatan ini juga. Namun, untuk pendekatan ini Anda memerlukan lebih banyak waktu henti daripada Pendekatan karena Anda harus menyinkronkan tabel.

Shashank Tiwari
sumber
6

Aaron Bertrand memiliki seri 4 bagian tentang topik ini, dimulai dengan:

Meminimalkan dampak pelebaran kolom IDENTITAS - bagian 1

Jika Anda benar-benar perlu pindah ke bigint, harus meminimalkan waktu henti, dan punya banyak waktu untuk perencanaan, pendekatan yang ia dokumentasikan di bagian 4 adalah:

Pada level yang sangat tinggi, pendekatannya adalah membuat seperangkat tabel bayangan, di mana semua sisipan diarahkan ke salinan tabel yang baru (dengan tipe data yang lebih besar), dan keberadaan dua set tabel sama transparannya. mungkin untuk aplikasi dan penggunanya.

Secara lebih rinci, Aaron berkata:

  1. Buat salinan bayangan dari tabel, dengan tipe data yang tepat.
  2. Ubah prosedur yang tersimpan (atau kode ad hoc) untuk menggunakan bigint untuk parameter. (Ini mungkin memerlukan modifikasi di luar daftar parameter, seperti variabel lokal, tabel temp, dll., Tetapi ini tidak terjadi di sini.)
  3. Ganti nama tabel lama, dan buat tampilan dengan nama-nama yang menyatukan tabel lama dan baru.
    • Tampilan tersebut akan memiliki alih-alih pemicu untuk mengarahkan operasi DML dengan benar ke tabel yang sesuai, sehingga data masih dapat dimodifikasi selama migrasi.
    • Ini juga mengharuskan SCHEMABINDING dikeluarkan dari setiap tampilan yang diindeks, tampilan yang ada untuk memiliki serikat antara tabel baru dan lama, dan prosedur yang bergantung pada SCOPE_IDENTITY () harus dimodifikasi.
  4. Migrasikan data lama ke tabel baru dalam potongan.
  5. Bersihkan, terdiri dari:
    • Menjatuhkan tampilan sementara (yang akan menjatuhkan BUKAN pemicu).
    • Mengganti nama tabel baru kembali ke nama aslinya.
    • Memperbaiki prosedur tersimpan untuk kembali ke SCOPE_IDENTITY ().
    • Menjatuhkan meja lama yang sekarang kosong.
    • Mengembalikan SCHEMABINDING pada tampilan yang diindeks dan membuat kembali indeks yang dikelompokkan.
Paul White 9
sumber