Apakah ada kerugian untuk selalu menggunakan nvarchar (MAX)?

342

Dalam SQL Server 2005, apakah ada kerugian untuk membuat semua bidang karakter nvarchar (MAX) daripada menentukan panjang secara eksplisit, misalnya nvarchar (255)? (Terlepas dari yang jelas bahwa Anda tidak dapat membatasi panjang bidang di tingkat basis data)

stucampbell
sumber
1
Saya juga tidak mengerti mengapa Anda ingin membiarkan seseorang memasukkan nama 8000+ karakter.
DForck42
2
Logika yang sama dapat diterapkan ke bahasa pemrograman. Mengapa tidak kembali ke varian VB6 lama untuk semua data kami? Saya tidak berpikir memiliki cek dan saldo di lebih dari satu tempat tentu buruk.
Matt Spradley
1
Periksa ini: stackoverflow.com/questions/2009694/…
Akira Yamamoto
10
Pembaruan Anda harus menjadi jawabannya sendiri untuk pertanyaan ini.
Johann
answer-in-question pindah ke jawaban yang benar karena penulis asli belum melakukannya. stackoverflow.com/a/35177895/10245 Saya pikir 7 tahun adalah waktu yang cukup :-)
Tim Abell

Jawaban:

153

Pertanyaan yang sama ditanyakan di Forum MSDN:

Dari pos asli (lebih banyak informasi di sana):

Saat Anda menyimpan data ke kolom VARCHAR (N), nilainya disimpan secara fisik dengan cara yang sama. Tetapi ketika Anda menyimpannya di kolom VARCHAR (MAX), di belakang layar data tersebut ditangani sebagai nilai TEXT. Jadi ada beberapa pemrosesan tambahan yang diperlukan ketika berhadapan dengan nilai VARCHAR (MAX). (hanya jika ukurannya melebihi 8000)

VARCHAR (MAX) atau NVARCHAR (MAX) dianggap sebagai 'tipe nilai besar'. Jenis nilai besar biasanya disimpan 'di luar baris'. Ini berarti bahwa baris data akan memiliki sebuah penunjuk ke lokasi lain di mana 'nilai besar' disimpan ...

David Kreps
sumber
2
Jadi seharusnya pertanyaannya adalah, apakah ada perbedaan antara menggunakan N / VARCHAR (MAX) dan N / TEXT?
Tanpa izin
18
Jika saya ingat dengan benar, bukankah mereka hanya disimpan di luar baris jika ukurannya melebihi 8k?
Sam Schutte
79
Saya membaca jawabannya sebagai "tidak, tidak ada kerugian untuk menggunakan N/VARCHAR(MAX)" karena ada pemrosesan tambahan "hanya jika ukurannya melebihi 8000". Dengan demikian, Anda hanya perlu mengeluarkan biaya saat diperlukan , dan basis data Anda tidak terlalu ketat . Apakah saya salah membaca ini? Sepertinya Anda hampir selalu menginginkannya N/VARCHAR(MAX)daripada N/VARCHAR(1-8000)...
Kent Boogaart
1
Tautan mati di atas - tautan yang berfungsi untuk pertanyaan pada MSDN adalah social.msdn.microsoft.com/Forums/en-US/sqlgetstarted/thread/…
Jagd
68
Sayangnya jawaban ini memiliki sejumlah masalah. Itu membuat batas 8k tampak seperti angka ajaib, tidak benar, nilainya akan didorong keluar dari barisan berdasarkan pada lebih banyak faktor, termasuk sp_tableoptions: msdn.microsoft.com/en-us/library/ms173530.aspx . Tipe VARCHAR (255) juga dapat didorong keluar dari baris, 'overhead' yang disebutkan mungkin persis sama untuk MAX dan 255. Tipe ini membandingkan tipe MAX dengan tipe TEXT, ketika mereka berbeda saat mendapat (sama sekali berbeda API untuk memanipulasi, penyimpanan yang berbeda dll). Gagal menyebutkan perbedaan yang sebenarnya: tidak ada indeks, tidak ada operasi online pada tipe MAX
Remus Rusanu
50

Itu pertanyaan yang wajar dan dia menyatakan selain dari yang sudah jelas ...

Kerugian dapat mencakup:

Implikasi kinerja. Optimizer kueri menggunakan ukuran bidang untuk menentukan rencana exectution paling efisien

"1. Alokasi ruang dalam ekstensi dan halaman-halaman database fleksibel. Dengan demikian ketika menambahkan informasi ke bidang menggunakan pembaruan, database Anda harus membuat pointer jika data baru lebih panjang dari yang dimasukkan sebelumnya. Ini file database akan menjadi terfragmentasi = kinerja yang lebih rendah di hampir semua hal, mulai dari indeks hingga dihapus, diperbarui, dan disisipkan. " http://sqlblogcasts.com/blogs/simons/archive/2006/02/28/Why-use-anything-but-varchar_2800_max_2900_.aspx

Implikasi integrasi - sulit bagi sistem lain untuk mengetahui bagaimana mengintegrasikan dengan database Anda Pertumbuhan data yang tidak dapat diprediksi Kemungkinan masalah keamanan misalnya Anda dapat membuat crash sistem dengan mengambil semua ruang disk

Ada artikel bagus di sini: http://searchsqlserver.techtarget.com/tip/1,289483,sid87_gci1098157,00.html

alexmac
sumber
4
+1 Untuk integrasi dan implikasi keamanan. Ini adalah sudut pandang asli untuk dipertimbangkan ketika sebagian besar jawaban lain berbicara tentang kinerja. Terkait dengan implikasi integrasi, setiap alat (seperti penulis laporan atau perancang formulir) yang menggunakan meta data untuk memberikan ukuran kontrol default yang wajar akan membutuhkan lebih banyak pekerjaan untuk digunakan jika semua kolom varchar(max).
Disillusioned
Integrasi dengan basis data adalah hal paling konyol yang saya tahu. Jika hanya impor dilakukan sekali Anda dapat memeriksa data sebelumnya dengan fungsi LEN.
Maxim
30

Berdasarkan tautan yang disediakan dalam jawaban yang diterima, tampak bahwa:

  1. 100 karakter yang disimpan dalam suatu nvarchar(MAX)bidang akan disimpan tidak berbeda dengan 100 karakter dalam suatu nvarchar(100)bidang - data akan disimpan sebaris dan Anda tidak akan memiliki overhead membaca dan menulis data 'di luar baris'. Jadi tidak perlu khawatir.

  2. Jika ukurannya lebih besar dari 4000 data akan disimpan 'di luar baris' secara otomatis, yang Anda inginkan. Jadi tidak ada kekhawatiran di sana.

Namun...

  1. Anda tidak dapat membuat indeks pada nvarchar(MAX)kolom. Anda dapat menggunakan pengindeksan teks lengkap, tetapi Anda tidak dapat membuat indeks pada kolom untuk meningkatkan kinerja kueri. Bagi saya, ini segel kesepakatan ... itu adalah kerugian yang pasti untuk selalu menggunakan nvarchar (MAX).

Kesimpulan:

Jika Anda menginginkan semacam "panjang string universal" di seluruh basis data Anda, yang dapat diindeks dan yang tidak akan membuang ruang dan waktu akses, maka Anda dapat menggunakannya nvarchar(4000).

Tim Abell
sumber
1
fyi ini adalah suntingan yang ditambahkan ke pertanyaan asli yang seharusnya diposting sebagai jawaban
Tim Abell
1
Terima kasih, bagi saya ini adalah jawaban terakhir. Saya bertanya pada diri sendiri sama - mengapa tidak digunakan nvarchar(max)sepanjang waktu - seperti stringdi C #? - tetapi poin 3) (masalah indeks) memberikan jawaban.
SQL Police
1
Menambahkan hasil edit. Sebagai semacam "panjang string universal", Anda selalu bisa menggunakannvarchar(4000)
SQL Police
@SQLGeorge Lihat jawaban yang sangat baik ini oleh Martin Smith tentang dampak terhadap permintaan kinerja dari pernyataan kolom yang lebih luas dari yang pernah ada
billinkc
@ Billinkc Terima kasih, itu artikel yang bagus. OK, jadi ukurannya memang mempengaruhi perfromance. Saya akan mengedit jawabannya lagi.
SQL Police
28

Terkadang Anda ingin tipe data untuk menerapkan beberapa pengertian pada data di dalamnya.

Katakan misalnya Anda memiliki kolom yang benar-benar tidak boleh lebih dari, katakanlah, 20 karakter. Jika Anda mendefinisikan kolom itu sebagai VARCHAR (MAX), beberapa aplikasi jahat bisa memasukkan string panjang ke dalamnya dan Anda tidak akan pernah tahu, atau punya cara untuk mencegahnya.

Kali berikutnya aplikasi Anda menggunakan string itu, dengan asumsi bahwa panjang string itu sederhana dan masuk akal untuk domain yang diwakilinya, Anda akan mengalami hasil yang tidak dapat diprediksi dan membingungkan.

Bill Karwin
sumber
9
Saya setuju dengan ini, dan beberapa komentar lainnya, tetapi saya tetap berpendapat bahwa ini adalah tanggung jawab tingkat bisnis. Pada saat ia mencapai tingkat basis data, ia harus memberi hormat dan menyimpan nilainya, tidak peduli seberapa lama itu. Saya pikir apa yang benar-benar berperan di sini adalah bahwa saya memikirkan sekitar 90% dari waktu ketika seorang pengembang menentukan varchar (255), maksudnya bukan benar-benar 255 karakter, tetapi beberapa nilai panjang lumayan tidak ditentukan. Dan mengingat trade off antara nilai-nilai besar yang tidak masuk akal dalam db dan pengecualian yang tidak terduga, saya akan mengambil nilai-nilai besar.
Chris B. Behrens
4
Jika mereka menentukan VARCHAR (255) untuk menunjukkan beberapa panjang yang tidak diketahui maka itu kesalahan mereka untuk tidak meneliti dengan benar apa yang mereka desain. Solusinya adalah bagi pengembang untuk melakukan pekerjaan mereka, bukan untuk database yang memungkinkan nilai-nilai yang tidak masuk akal.
Tom H
10
tidak membantu penulis. dia secara eksplisit mengecualikan pertanyaan yang Anda berikan jawabannya.
usr
6
@ Chris B Behrens: Saya tidak setuju; skema basis data adalah bagian dari logika bisnis. Pilihan tabel, relasi, bidang, dan tipe data semuanya adalah logika bisnis - dan layak menggunakan RDBMS untuk menegakkan aturan logika bisnis ini. Untuk satu alasan, sangat jarang bahwa hanya ada satu tingkat aplikasi mengakses database; misalnya Anda mungkin memiliki alat impor dan ekstraksi data yang memotong tingkat bisnis utama, yang berarti Anda benar-benar membutuhkan DB untuk menegakkan aturan.
Vince Bowdren
1
Jika Anda tidak perlu atau memang ingin string panjang disimpan, maka lebih baik untuk menegakkan rasa pada data. Misalnya, jika menyimpan bidang PostCode, apakah Anda akan membiarkan seseorang memasukkan ratusan atau ribuan karakter padahal seharusnya maksimum 10 katakan.- ukuran maksimal harus divalidasi semua tingkat, klien, tingkat bisnis DAN basis data. Jika menggunakan pendekatan Model Pertama seperti dengan C # dan Kerangka Entitas, Anda dapat menentukan Anda memaksimalkan pada model dan menerapkannya ke database, logika bisnis, dan validasi klien (dengan suka validasi jquery). Hanya gunakan nvarchar (maks) jika benar-benar diperlukan
Peter Kerr
21

Saya memeriksa beberapa artikel dan menemukan skrip uji yang berguna dari ini: http://www.sqlservercentral.com/Forums/Topic1480639-1292-1.aspx Kemudian mengubahnya untuk membandingkan antara NVARCHAR (10) vs NVARCHAR (4000) vs NVARCHAR (MAX) ) dan saya tidak menemukan perbedaan kecepatan saat menggunakan angka yang ditentukan tetapi saat menggunakan MAX. Anda dapat menguji sendiri. Semoga ini bisa membantu.

SET NOCOUNT ON;

--===== Test Variable Assignment 1,000,000 times using NVARCHAR(10)
DECLARE @SomeString NVARCHAR(10),
        @StartTime DATETIME;
--=====         
 SELECT @startTime = GETDATE();
 SELECT TOP 1000000
        @SomeString = 'ABC'
   FROM master.sys.all_columns ac1,
        master.sys.all_columns ac2;
 SELECT testTime='10', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO
--===== Test Variable Assignment 1,000,000 times using NVARCHAR(4000)
DECLARE @SomeString NVARCHAR(4000),
        @StartTime DATETIME;
 SELECT @startTime = GETDATE();
 SELECT TOP 1000000
        @SomeString = 'ABC'
   FROM master.sys.all_columns ac1,
        master.sys.all_columns ac2;
 SELECT testTime='4000', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO
--===== Test Variable Assignment 1,000,000 times using NVARCHAR(MAX)
DECLARE @SomeString NVARCHAR(MAX),
        @StartTime DATETIME;
 SELECT @startTime = GETDATE();
 SELECT TOP 1000000
        @SomeString = 'ABC'
   FROM master.sys.all_columns ac1,
        master.sys.all_columns ac2;
 SELECT testTime='MAX', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO
QMaster
sumber
4
Itu menarik. Di kotak saya sepertinya MAX yang 4x lebih lambat.
stucampbell
4
Hasil baru pada SQL Server 2012: 10 dua kali lebih lambat dari 4k dan MAX 5,5 kali lebih lambat dari 4k.
cassandrad
1
Sebagian besar waktu adalah pemeran implisit dari varchar ke nvarchar (maks). Coba yang ini: DECLARE \ @SomeString NVARCHAR (MAX), \ @abc NVARCHAR (maks) = N'ABC ', \ @StartTime DATETIME; SELECT @startTime = GETDATE (); PILIH TOP 1000000 \ @SomeString = \ @abc DARI master.sys.all_columns ac1, master.sys.all_columns ac2; SELECT testTime = 'MAX', Durasi = DATEDIFF (ms, \ @ StartTime, GETDATE ()); Harus memasukkan \ sebelum variabel untuk mengirimnya.
Kvasi
4
SQL Server 2014 pada SSD: 150, 156, 716 (10, 4000, MAX).
Maxim
2
Terima kasih telah menambahkan beberapa bilangan real ke diskusi ini. Kita sering lupa bahwa membangun test case adalah cara tercepat untuk mendapatkan wawasan.
David C
13

Anggap saja sebagai tingkat keamanan lain. Anda bisa mendesain meja Anda tanpa hubungan kunci asing - benar-benar valid - dan memastikan keberadaan entitas terkait sepenuhnya di lapisan bisnis. Namun, kunci asing dianggap praktik desain yang baik karena mereka menambah tingkat kendala lain jika terjadi sesuatu yang kacau pada lapisan bisnis. Hal yang sama berlaku untuk batasan ukuran bidang dan tidak menggunakan varchar MAX.

Alex
sumber
8

Alasan TIDAK untuk menggunakan bidang max atau teks adalah bahwa Anda tidak dapat melakukan pembangunan kembali indeks online yaitu MEMBANGUN KEMBALI DENGAN ONLINE = HIDUP bahkan dengan SQL Server Enterprise Edition.

Nick Kavadias
sumber
1
Pembatasan yang sama ini berlaku untuk jenis bidang TEXT, jadi Anda harus tetap menggunakan VARCHAR (MAX) alih-alih TEXT.
Will Shaver
kami tidak dapat membangun kembali indeks berkerumun kami karena ini. kami menghabiskan banyak ruang disk hingga kami dapat mengekstraksi kolom ke dalam tabelnya sendiri (kami tidak dapat mengunci tabel lebih dari 7 detik)
Choco Smith
4

Satu-satunya masalah yang saya temukan adalah bahwa kami mengembangkan aplikasi kami pada SQL Server 2005, dan dalam satu contoh, kami harus mendukung SQL Server 2000. Saya baru belajar, betapa sulitnya SQL Server 2000 tidak menyukai opsi MAX untuk varchar atau nvarchar.

mattruma
sumber
2
Jadi mengapa tidak mengembangkan pada common denominator terendah?
binki
4

Gagasan buruk ketika Anda tahu bidangnya akan berada dalam kisaran set- 5 hingga 10 karakter misalnya. Saya pikir saya hanya akan menggunakan maks jika saya tidak yakin berapa panjangnya. Misalnya nomor telepon tidak akan pernah lebih dari jumlah karakter tertentu.

Bisakah Anda dengan jujur ​​mengatakan bahwa Anda tidak yakin tentang persyaratan panjang perkiraan untuk setiap bidang di tabel Anda?

Saya mengerti maksud Anda - ada beberapa bidang yang saya pasti akan pertimbangkan untuk menggunakan varchar (maks).

Menariknya, dokumen MSDN merangkumnya dengan cukup baik:

Gunakan varchar ketika ukuran entri data kolom sangat bervariasi. Gunakan varchar (maks) ketika ukuran entri data kolom sangat bervariasi, dan ukurannya mungkin melebihi 8.000 byte.

Ada diskusi menarik tentang masalah ini di sini .

RichardOD
sumber
2
Untuk hal-hal seperti nomor telepon, saya akan jauh lebih setuju untuk menggunakan bidang char daripada varchar. Selama Anda mempertahankan standar dalam penyimpanan Anda dan Anda tidak perlu khawatir tentang nomor telepon dari berbagai negara, Anda seharusnya tidak perlu bidang variabel untuk sesuatu seperti nomor telepon (10 tanpa format) atau kode pos (5) atau 9-10 jika Anda menambahkan empat digit terakhir), dll.
TheTXI
Saya mengacu pada nomor telepon yang panjangnya bisa bervariasi. Mungkin aku harus menjawab ini. Apa pun yang panjangnya tetap saya akan menggunakan bidang char.
RichardOD
Atau mungkin saya harus mengatakan dalam komentar saya nchar atau char. :-)
RichardOD
2
Jumlah karakter dalam nomor telepon cukup banyak merupakan persyaratan bisnis. Jika Anda diharuskan menyimpan kode standar internasional beserta nomornya, bisa jadi lebih dari 10. Atau, beberapa bagian dunia mungkin memiliki lebih dari 10 digit untuk nomor telepon. Bayangkan kasus transisi IPV4 ke IPV6. Tidak ada yang akan berpendapat bahwa kami membutuhkan lebih dari 12 digit di hari-hari IPV4 lama yang baik. Ini mungkin tidak berlaku jika IPV6 menjadi lazim. Lagi-lagi ini adalah perubahan aturan bisnis selama periode waktu tertentu. Seperti yang dikatakan, perubahan adalah satu-satunya hal yang konstan yang dapat kita harapkan :)
pencilslate
2
Berhati-hatilah dengan asumsi Anda tahu jumlah karakter di bidang nomor telepon, atau karakter seperti apa mereka. Kecuali jika sistem menggunakan data tersebut untuk benar-benar keluar (dalam hal ini Anda harus ketat tentang format), maka pengguna mungkin secara sah menempatkan string panjang yang tak terduga di sana misalnya "0123 456 78910 meminta penerimaan untuk ekstensi 45 dan kemudian transfer ke James".
Vince Bowdren
4

Tugas dari database adalah menyimpan data sehingga dapat digunakan oleh perusahaan. Bagian dari pembuatan data yang bermanfaat adalah memastikan bahwa data itu bermakna. Mengizinkan seseorang untuk memasukkan jumlah karakter yang tidak terbatas untuk nama depan mereka tidak menjamin data yang bermakna.

Membangun batasan-batasan ini ke dalam lapisan bisnis adalah ide yang bagus, tetapi itu tidak memastikan bahwa database akan tetap utuh. Satu-satunya cara untuk menjamin bahwa aturan data tidak dilanggar adalah dengan menegakkannya pada tingkat serendah mungkin dalam database.

Tom H
sumber
6
IMO, batasan panjang data murni berdasarkan pada aturan bisnis, yang dapat berubah selama periode waktu tertentu, seiring dengan pertumbuhan aplikasi. Mengubah aturan bisnis pada logika bisnis lebih mudah daripada di level db. Jadi, saya pikir db harus cukup fleksibel dan tidak boleh dikaitkan dengan aturan bisnis seperti panjang maksimum yang diizinkan nama depan, yang sangat tergantung pada bagian dunia tempat Anda tinggal.
pencilslate
3

Satu masalah adalah bahwa jika Anda harus bekerja dengan beberapa versi SQL Server, MAX tidak akan selalu berfungsi. Jadi, jika Anda bekerja dengan warisan DB atau situasi lain yang melibatkan banyak versi, Anda sebaiknya berhati-hati.

TheTXI
sumber
Saya pikir asumsi tak terucapkan pada bagian OP adalah bahwa ia berurusan sepenuhnya dengan contoh 2005+, dan bahwa aplikasinya tidak perlu bekerja pada 2000 (atau, ack, lebih rendah) versi. Saya sepenuhnya setuju dengan Anda jika ada kebutuhan untuk mendukung versi yang lebih lama!
John Rudy
John Rudy: Saya akan membayangkan itu yang terjadi, saya hanya tahu bahwa saya telah mengalami sendiri rintangan-rintangan itu ketika saya tidak berpikir saya akan melakukannya.
TheTXI
Sebenarnya ini adalah masalah umum masih dengan hal-hal modern karena SQL CE 4 yang tidak mendukung tipe kolom MAX sehingga interoperabilitas adalah masalah.
JohnC
3

Seperti yang ditunjukkan di atas, ini terutama merupakan pertukaran antara penyimpanan dan kinerja. Setidaknya dalam banyak kasus.

Namun, setidaknya ada satu faktor lain yang harus dipertimbangkan ketika memilih n / varchar (Max) daripada n / varchar (n). Apakah data akan diindeks (seperti, misalnya, nama belakang)? Karena definisi MAX dianggap sebagai LOB, maka apa pun yang didefinisikan sebagai MAX tidak tersedia untuk pengindeksan. dan tanpa indeks, pencarian apa pun yang melibatkan data sebagai predikat dalam klausa WHERE akan dipaksa ke pemindaian Tabel Penuh, yang merupakan kinerja terburuk yang bisa Anda dapatkan untuk pencarian data.

Harry Cooper
sumber
2

1) Server SQL harus menggunakan lebih banyak sumber daya (memori yang dialokasikan dan waktu cpu) ketika berhadapan dengan nvarchar (max) vs nvarchar (n) di mana n adalah angka khusus untuk bidang tersebut.

2) Apa artinya ini dalam hal kinerja?

Pada SQL Server 2005, saya menanyakan 13.000 baris data dari tabel dengan 15 nvarchar (maks) kolom. Saya menghitung waktu kueri berulang kali dan kemudian mengubah kolom menjadi nvarchar (255) atau kurang.

Permintaan sebelum optimasi rata-rata pada 2,0858 detik. Permintaan setelah perubahan kembali dalam rata-rata 1,90 detik. Itu sekitar 184 milidetik perbaikan untuk kueri pemilihan * dasar. Itu adalah peningkatan 8,8%.

3) Hasil saya sesuai dengan beberapa artikel lain yang menunjukkan bahwa ada perbedaan kinerja. Bergantung pada basis data dan kueri Anda, persentase peningkatan dapat bervariasi. Jika Anda tidak memiliki banyak pengguna bersamaan atau sangat banyak catatan, maka perbedaan kinerja tidak akan menjadi masalah bagi Anda. Namun, perbedaan kinerja akan meningkat karena lebih banyak catatan dan pengguna secara bersamaan meningkat.

WWC
sumber
1

Saya punya udf yang berisi string dan menempatkan output ke varchar (maks). Jika ini digunakan secara langsung, bukan casting kembali ke ukuran yang sesuai untuk kolom yang disesuaikan, kinerjanya sangat buruk. Saya akhirnya menempatkan udf ke panjang yang sewenang-wenang dengan catatan besar alih-alih mengandalkan semua penelepon udf untuk melemparkan kembali string ke ukuran yang lebih kecil.

Cade Roux
sumber
1

dukungan sistem warisan. Jika Anda memiliki sistem yang menggunakan data dan diharapkan memiliki panjang tertentu, maka basis data adalah tempat yang baik untuk menegakkan panjang. Ini tidak ideal tetapi sistem warisan terkadang tidak ideal. = P

Tony
sumber
1

Jika semua data dalam satu baris (untuk semua kolom) tidak akan pernah cukup mengambil 8000 atau lebih sedikit karakter maka desain pada lapisan data harus memberlakukan ini.

Mesin database jauh lebih efisien menjaga semuanya dari penyimpanan gumpalan. Semakin kecil Anda dapat membatasi baris, semakin baik. Semakin banyak baris Anda dapat menjejalkan di halaman lebih baik. Basis data hanya berkinerja lebih baik ketika harus mengakses lebih sedikit halaman.

Matt Spradley
sumber
1

Tes saya menunjukkan bahwa ada perbedaan saat memilih.

CREATE TABLE t4000 (a NVARCHAR(4000) NULL);

CREATE TABLE tmax (a NVARCHAR(MAX) NULL);

DECLARE @abc4 NVARCHAR(4000) = N'ABC';

INSERT INTO t4000
SELECT TOP 1000000 @abc4
    FROM
    master.sys.all_columns ac1,
    master.sys.all_columns ac2;

DECLARE @abc NVARCHAR(MAX) = N'ABC';

INSERT INTO tmax
SELECT TOP 1000000 @abc
    FROM
    master.sys.all_columns ac1,
    master.sys.all_columns ac2;

SET STATISTICS TIME ON;
SET STATISTICS IO ON;

SELECT * FROM dbo.t4000;
SELECT * FROM dbo.tmax;
Kvasi
sumber
0

Tautan yang menarik: Mengapa menggunakan VARCHAR saat Anda dapat menggunakan TEXT?

Ini tentang PostgreSQL dan MySQL, jadi analisis kinerjanya berbeda, tetapi logika untuk "explicitness" masih berlaku: Mengapa memaksakan diri untuk selalu khawatir tentang sesuatu yang relevan dengan persentase kecil dari waktu? Jika Anda menyimpan alamat email ke variabel, Anda akan menggunakan 'string' bukan 'string yang dibatasi hingga 80 karakter'.

orip
sumber
1
Itu mirip dengan argumen bahwa Anda seharusnya tidak memiliki batasan untuk memastikan bahwa usia seseorang bukan angka negatif.
Jonathan Allen
Saya melihat perbedaan antara kebenaran data dan optimalisasi kinerja.
orip
0

Kerugian utama yang bisa saya lihat adalah katakanlah Anda memiliki ini:

Yang mana yang memberi Anda informasi paling banyak tentang data yang diperlukan untuk UI?

Ini

            CREATE TABLE [dbo].[BusData](
                [ID] [int] IDENTITY(1,1) NOT NULL,
                [RecordId] [nvarchar](MAX) NULL,
                [CompanyName] [nvarchar](MAX) NOT NULL,
                [FirstName] [nvarchar](MAX) NOT NULL,
                [LastName] [nvarchar](MAX) NOT NULL,
                [ADDRESS] [nvarchar](MAX) NOT NULL,
                [CITY] [nvarchar](MAX) NOT NULL,
                [County] [nvarchar](MAX) NOT NULL,
                [STATE] [nvarchar](MAX) NOT NULL,
                [ZIP] [nvarchar](MAX) NOT NULL,
                [PHONE] [nvarchar](MAX) NOT NULL,
                [COUNTRY] [nvarchar](MAX) NOT NULL,
                [NPA] [nvarchar](MAX) NULL,
                [NXX] [nvarchar](MAX) NULL,
                [XXXX] [nvarchar](MAX) NULL,
                [CurrentRecord] [nvarchar](MAX) NULL,
                [TotalCount] [nvarchar](MAX) NULL,
                [Status] [int] NOT NULL,
                [ChangeDate] [datetime] NOT NULL
            ) ON [PRIMARY]

Atau ini?

            CREATE TABLE [dbo].[BusData](
                [ID] [int] IDENTITY(1,1) NOT NULL,
                [RecordId] [nvarchar](50) NULL,
                [CompanyName] [nvarchar](50) NOT NULL,
                [FirstName] [nvarchar](50) NOT NULL,
                [LastName] [nvarchar](50) NOT NULL,
                [ADDRESS] [nvarchar](50) NOT NULL,
                [CITY] [nvarchar](50) NOT NULL,
                [County] [nvarchar](50) NOT NULL,
                [STATE] [nvarchar](2) NOT NULL,
                [ZIP] [nvarchar](16) NOT NULL,
                [PHONE] [nvarchar](18) NOT NULL,
                [COUNTRY] [nvarchar](50) NOT NULL,
                [NPA] [nvarchar](3) NULL,
                [NXX] [nvarchar](3) NULL,
                [XXXX] [nvarchar](4) NULL,
                [CurrentRecord] [nvarchar](50) NULL,
                [TotalCount] [nvarchar](50) NULL,
                [Status] [int] NOT NULL,
                [ChangeDate] [datetime] NOT NULL
            ) ON [PRIMARY]
carlos martini
sumber
3
Saya lebih suka logika bisnis memberi tahu saya bahwa Nama Perusahaan dapat maksimal 50 karakter daripada mengandalkan tabel database untuk info itu.
Khan
Saya setuju dengan Jeff. Saya tidak berpikir toko kegigihan adalah tempat yang tepat untuk mendefinisikan aturan bisnis Anda. Dan dalam arsitektur berlapis UI Anda bahkan tidak akan tahu tentang lapisan kegigihan.
stucampbell
Kecuali tentu saja Anda menggunakan nilai yang dibatasi pada ukuran tertentu, misalnya kode ISO untuk negara.
Ben
2
Apa hubungannya dengan def tabel? Anda masih dapat memiliki logika bisnis. Saya pikir poin Anda tidak masuk akal terkait dengan bagaimana sebuah tabel dirancang. Jika Anda masih ingin merancang semacam definisi di lapisan bisnis Anda, maka jadilah itu. Meskipun yang lebih masuk akal, tetap menggunakan proc yang tersimpan di lapisan bisnis; bukan def tabel ??
carlos martini
1
Tampaknya tidak populer tetapi saya setuju dengan carlos, jika db menetapkan ukuran maksimal maka Anda dapat merasa nyaman di semua lapisan yang Anda bangun di atasnya apa yang Anda harus hadapi. Ini sangat penting jika Anda memiliki banyak sistem yang menulis ke basis data Anda.
Tim Abell
0

Salah satu kelemahannya adalah bahwa Anda akan mendesain di sekitar variabel yang tidak dapat diprediksi, dan Anda mungkin akan mengabaikan alih-alih memanfaatkan struktur data SQL Server internal, yang secara progresif terdiri dari Baris, Halaman, dan Luas.

Yang membuat saya berpikir tentang penyelarasan struktur data dalam C, dan bahwa menyadari penyelarasan umumnya dianggap sebagai Good Thing (TM). Ide serupa, konteksnya berbeda.

Halaman MSDN untuk Halaman dan Luas

Halaman MSDN untuk Data Row-Overflow

tsundoku
sumber
0

pertama saya memikirkan hal ini, tetapi kemudian berpikir lagi. Ada implikasi kinerja, tetapi sama-sama berfungsi sebagai bentuk dokumentasi untuk memiliki gagasan ukuran bidang apa sebenarnya. Dan itu berlaku ketika database itu berada di ekosistem yang lebih besar. Menurut saya kuncinya adalah permisif tetapi hanya masuk akal.

ok, inilah perasaan saya hanya pada masalah logika bisnis dan lapisan data. Itu tergantung, jika DB Anda adalah sumber daya bersama antara sistem yang berbagi logika bisnis maka tentu saja itu tampaknya tempat alami untuk menegakkan logika tersebut, tetapi itu bukan cara TERBAIK untuk melakukannya, cara TERBAIK adalah menyediakan API, ini memungkinkan interaksi yang akan diuji dan membuat logika bisnis tetap berada di tempatnya, ia membuat sistem dipisahkan, menjaga tingkatan Anda dalam sistem dipisahkan. Namun, jika database Anda seharusnya hanya melayani satu aplikasi, maka mari kita berpikir, apa yang benar sekarang? desain untuk saat ini. Jika dan ketika akses tersebut diperlukan, berikan API ke data itu.

jelas, ini hanya yang ideal, jika Anda bekerja dengan sistem yang ada, kemungkinannya adalah bahwa Anda perlu melakukannya secara berbeda setidaknya dalam jangka pendek.

Stephen Whipp
sumber
-1

Ini akan menyebabkan masalah kinerja, meskipun mungkin tidak pernah menyebabkan masalah aktual jika database Anda kecil. Setiap catatan akan memakan lebih banyak ruang di hard drive dan database akan perlu membaca lebih banyak sektor disk jika Anda mencari melalui banyak catatan sekaligus. Misalnya, catatan kecil bisa muat 50 untuk sektor dan catatan besar bisa muat 5. Anda harus membaca 10 kali lebih banyak data dari disk menggunakan catatan besar.

Dan Goldstein
sumber
5
-1. String dengan panjang 100 yang disimpan dalam nvarchar(max)kolom tidak membutuhkan ruang disk lebih banyak daripada jika berada dalam nvarchar(100)kolom.
Martin Smith
Apa yang Anda uraikan benar jika ukuran data yang disimpan lebih besar, tetapi pertanyaan ini adalah tentang apakah tipe data memiliki implikasi kinerja atau pertimbangan lain.
-2

Ini akan membuat desain layar lebih sulit karena Anda tidak lagi dapat memprediksi seberapa lebar kontrol Anda seharusnya.

pappes
sumber