Pertama, terima kasih telah melakukan ini. Ini adalah kemenangan yang jelas sehingga banyak yang tidak melihat banyak nilai, tetapi itu akan sangat berharga :). Membuat dunia sedikit lebih waras.
Mengenai IsActive
menjadi boolean. Dugaan saya adalah Anda berpikir untuk menjadikannya BIT
bidang. Itu mungkin cara yang harus dilakukan, tetapi terkadang lebih baik menggunakan TINYINT
karena ada kemungkinan memperluas makna menjadi lebih dari 2 keadaan. Dalam hal ini benar-benar menjadi lebih dari StatusID
. Biasanya ini adalah kasus sesuatu yang dimulai secara sederhana sebagai Aktif / Tidak aktif , tapi nanti mungkin Dihapus dan/atau lainnya. Dari perspektif ukuran, TINYINT
selalu 1 byte. Sebaliknya, BIT
adalah 1 byte hingga 8 BIT
bidang . Artinya, satu BIT
bidang adalah 1 byte, 2 BIT
bidang juga satu byte, dan seterusnya hingga 8 BIT
bidang yang disimpan dalam satu byte. Jadi, tidak ada penghematan ruang memilih BIT
lebih dari TINYINT
ketika tabel hanya memiliki 1 BIT
bidang. Hanya sesuatu yang perlu dipertimbangkan.
Melakukan ALTER TABLE agak banyak untuk tabel besar, seperti yang Anda lihat. Salah satu opsi, meskipun tidak bagus, adalah menambahkan NOT NULL
bidang--Number_1new
--dengan DEFAULT
value (ini akan terjadi seketika karena default, setidaknya dimulai dengan SQL 2012) yang tidak dimiliki secara alami (misalnya 255), dan kemudian secara perlahan memigrasikan nilai, dalam satu lingkaran, seperti pada:
UPDATE TOP (5000) tab
SET tab.Number_1new = tab.Number_1
FROM [table] tab
WHERE tab.Number_1new = 255;
Dan jika sudah selesai lakukan:
sp_rename 'table.Number_1', 'Number_1old', 'COLUMN';
sp_rename 'table.Number_1new', 'Number_1', 'COLUMN';
Tentu saja, yang terbaik adalah membungkusnya dalam TRANSAKSI, dan membungkusnya dengan TRY / CATCH. Ketika kode terkait telah diperbarui dan semuanya telah diuji dan data terlihat bagus, maka Anda dapat melepaskan Number_1old
kolom.
Namun, cara terbaik yang saya temukan adalah membuat tabel baru, perlahan-lahan mentransisikan data, lalu menukar tabel dan kode secara bersamaan. Saya merinci langkah-langkahnya dalam artikel di SQL Server Central:Restrukturisasi 100 Juta Baris (atau lebih) Tabel dalam Detik. SRSLY! (perlu pendaftaran gratis). Untuk berjaga-jaga jika ada masalah dalam mengakses artikel tersebut, berikut adalah langkah-langkah dasarnya:
- Buat tabel baru dengan struktur ideal--[tableNew]. Jika Anda menggunakan Edisi Perusahaan, pertimbangkan untuk mengaktifkan kompresi ROW atau PAGE karena terkadang dapat membantu. Tapi tolong lakukan penelitian terlebih dahulu karena ada beberapa situasi ketika mereka memiliki efek negatif. Ada dokumentasi di MSDN untuk membantu Anda mengetahuinya serta beberapa alat untuk membantu memperkirakan potensi penghematan. Tetapi bahkan jika Anda mengaktifkan kompresi, saya tidak akan melihat tindakan itu sebagai pengganti proyek yang Anda lakukan di sini.
- Tambahkan pemicu
AFTER UPDATE, DELETE
di [table] agar perubahan tetap sinkron (tetapi tidak perlu khawatir tentang baris baru) - Buat Pekerjaan Agen SQL yang memindahkan baris yang hilang dalam kumpulan. Lakukan ini dalam satu lingkaran yang melakukan
INSERT INTO [tableNew] (Columns) SELECT TOP (n) Columns FROM [table] WHERE ?? ORDER BY ??
- Klausa WHERE dan ORDER BY bergantung pada situasinya. Mereka harus diarahkan untuk memanfaatkan indeks berkerumun sebaik-baiknya. Jika indeks cluster dari tabel baru secara struktural sama dengan tabel lama/saat ini, maka pada awal setiap loop Anda bisa mendapatkan MAX([id]) dari [tableNew] dan menggunakannya untuk mendapatkan tabel
WHERE table.[id] > @MaxIdInTableNew ORDER BY table.[id]
. - Buat tabel baru, pemicu pada tabel saat ini, dan SQL Agent Job seminggu atau lebih sebelum Anda perlu melakukan cut-over penuh. Kerangka waktu itu mungkin berubah berdasarkan situasi Anda, tetapi pastikan untuk memberi diri Anda banyak waktu. Jauh lebih baik bagi pekerjaan untuk menyelesaikan migrasi baris dan hanya memiliki sedikit tetesan dalam satu waktu daripada harus 100 ribu lebih malu dari set lengkap karena rilis seharusnya dimulai.
- Jika rencananya adalah untuk memigrasi tabel terkait lainnya (referensi PK untuk dua FK yang ingin Anda ubah menjadi
INT
s), lalu buat bidang tersebut di siniINT
sekarang dan jangan tambahkan FK sampai tabel lain tersebut dimigrasikan untuk memiliki bidang INT sebagai PK mereka. Anda tidak ingin membangun kembali tabel ini hanya untuk membuat perubahan pada kolom FK. - Selama cut-over (dalam TRY / CATCH, tentu saja):
- MULAI TRANS
- lakukan penghitungan baris terakhir pada kedua tabel untuk memastikan semuanya dipindahkan (mungkin ingin memeriksa kewarasan baris sebelum rilis untuk memastikan bahwa pemicu melakukan pembaruan dan penghapusan seperti yang diharapkan)
- ganti nama tabel saat ini menjadi "lama"
- ganti nama tabel "baru" menjadi tidak "baru"
- lepaskan tugas Agen SQL (atau setidaknya nonaktifkan)
- ganti nama dan objek dependen seperti batasan, dll
- KOMITMEN