Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Mengatasi batas kolom maksimum SQL Server 1024 dan ukuran catatan 8kb

Ini tidak mungkin. Lihat Di dalam Mesin Penyimpanan:Anatomi catatan

Dengan asumsi tabel Anda seperti ini.

CREATE TABLE T1(
    col_1 varchar(8000) NULL,
    col_2 varchar(8000) NULL,
    /*....*/
    col_999 varchar(8000) NULL,
    col_1000 varchar(8000) NULL
) 

Kemudian bahkan satu baris dengan semua NULL nilai akan menggunakan penyimpanan berikut.

  • 1 bit status bit A
  • 1 bit status bit B
  • Oset jumlah kolom 2 byte
  • 125 byte NULL_BITMAP (1 bit per kolom untuk 1.000 kolom)

Jadi dijamin 129 byte sudah terpakai (meninggalkan 7.931).

Jika salah satu kolom memiliki nilai yang bukan NULL atau string kosong maka Anda juga membutuhkan ruang untuk

  • 2 byte jumlah kolom panjang variabel (meninggalkan 7.929).
  • Di mana saja antara 2 - 2000 byte untuk larik offset kolom.
  • Data itu sendiri.

Larik offset kolom menggunakan 2 byte per panjang variabel kolom kecuali jika kolom itu dan semua kolom berikutnya juga panjangnya nol. Jadi perbarui col_1000 akan memaksa seluruh 2000 byte untuk digunakan saat memperbarui col_1 hanya akan menggunakan 2 byte.

Jadi, Anda dapat mengisi setiap kolom dengan 5 byte data dan dengan mempertimbangkan masing-masing 2 byte dalam larik offset kolom yang akan menambahkan hingga 7.000 byte yang berada dalam sisa 7.929.

Namun data yang Anda simpan adalah 102 byte (51 nvarchar karakter) sehingga ini dapat disimpan di luar baris dengan penunjuk 24 byte ke data aktual yang tersisa di baris.

FLOOR(7929/(24 + 2)) = 304

Jadi kasus terbaiknya adalah Anda dapat menyimpan 304 kolom dari data panjang ini dan itu jika Anda memperbarui dari col_1 , col_2 , ... . Jika col_1000 berisi data maka perhitungannya adalah

FLOOR(5929/24) = 247

Untuk NTEXT perhitungannya mirip kecuali dapat menggunakan pointer 16 byte yang memungkinkan Anda memasukkan data ke dalam beberapa kolom tambahan

FLOOR(7929/(16 + 2)) = 440

Kebutuhan untuk mengikuti semua petunjuk di luar baris ini untuk setiap SELECT bertentangan dengan meja kemungkinan akan sangat merusak kinerja.

Script untuk menguji ini

DROP TABLE T1

/* Create table with 1000 columns*/
DECLARE @CreateTableScript nvarchar(max) = 'CREATE TABLE T1('

SELECT @CreateTableScript += 'col_' + LTRIM(number) + ' VARCHAR(8000),'
FROM master..spt_values
WHERE type='P' AND number BETWEEN 1 AND 1000
ORDER BY number

SELECT @CreateTableScript += ')'

EXEC(@CreateTableScript)

/* Insert single row with all NULL*/
INSERT INTO T1 DEFAULT VALUES


/*Updating first 304 cols succeed. Change to 305 and it fails*/
DECLARE @UpdateTableScript nvarchar(max) = 'UPDATE T1 SET  '

SELECT @UpdateTableScript += 'col_' + LTRIM(number) + ' = REPLICATE(1,1000),'
FROM master..spt_values
WHERE type='P' AND number BETWEEN 1 AND 304
ORDER BY number

SET @UpdateTableScript = LEFT(@UpdateTableScript,LEN(@UpdateTableScript)-1)
EXEC(@UpdateTableScript)


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Ubah format waktu tanggal default pada satu database di SQL Server

  2. Menggunakan Tampilan SQL dari Kode Kerangka Entitas Versi pertama 5

  3. Menggunakan Dapper dengan Tipe Spasial SQL sebagai parameter

  4. Kinerja Query SQL Server 2005

  5. DATEDIFF() vs DATEDIFF_BIG() di SQL Server:Apa Bedanya?