Apa praktik terbaik saat ini mengenai ukuran varchar di SQL Server?


12

Saya mencoba memahami cara terbaik untuk memutuskan seberapa besar kolom varchar seharusnya, baik dari perspektif penyimpanan dan kinerja.

Kinerja
Dari penelitian saya, tampaknyabahwa varchar (maks) hanya boleh digunakan jika Anda benar-benar membutuhkannya; yaitu, jika kolom harus mengakomodasi lebih dari 8000 karakter, salah satu alasannya adalah kurangnya pengindeksan (meskipun saya sedikit curiga pada pengindeksan pada bidang varchar secara umum. Namun saya cukup baru untuk prinsip-prinsip DB, jadi mungkin itu tidak berdasar ) dan kompresi (lebih merupakan masalah penyimpanan). Bahkan, secara umum orang-orang tampaknya merekomendasikan hanya menggunakan apa yang Anda butuhkan, ketika melakukan varchar (n) .... terlalu besar, karena permintaan harus memperhitungkan ukuran maksimum yang mungkin. Tetapi juga telah dinyatakan bahwa mesin akan menggunakan setengah dari ukuran yang ditunjukkan sebagai perkiraan dari ukuran aktual rata-rata data. Ini akan menyiratkan bahwa seseorang harus menentukan, dari data, apa ukuran rata-rata, gandakan, dan gunakan itu sebagai n. Untuk data dengan variabilitas yang sangat rendah tetapi tidak nol, ini menyiratkan hingga 2x melebihi ukuran maksimum, yang sepertinya banyak, tapi mungkin tidak? Wawasan akan dihargai.

Penyimpanan
Setelah membaca tentang bagaimana di-baris vs out-of-baris karya penyimpanan, dan dengan mengingat bahwa penyimpanan sebenarnya terbatas pada data aktual, itu benar-benar tampak bagi saya bahwa pilihan n memiliki sedikit atau tidak ada bantalan pada penyimpanan (selain Memastikan itu cukup besar untuk menampung semuanya). Bahkan menggunakan varchar (maks) tidak akan berdampak pada penyimpanan. Alih-alih, sasaran mungkin untuk membatasi ukuran aktual setiap baris data hingga ~ 8000 byte jika memungkinkan. Apakah itu pembacaan yang akurat tentang berbagai hal?

Konteks
Beberapa data pelanggan kami sedikit berfluktuasi, jadi kami biasanya membuat kolom sedikit lebih lebar dari yang seharusnya, katakanlah 15-20% lebih besar, untuk kolom-kolom itu. Saya bertanya-tanya apakah ada pertimbangan khusus lainnya; misalnya, seseorang yang bekerja dengan saya mengatakan kepada saya untuk menggunakan ukuran 2 ^ n - 1 (saya belum menemukan bukti bahwa itu masalah ....)

Saya berbicara tentang pembuatan tabel awal. Seorang pelanggan akan memberi tahu kami bahwa mereka akan mulai mengirimkan kepada kami tabel baru, dan mengirimkan data sampel (atau hanya kumpulan data produksi pertama), yang kami lihat dan buat tabel di ujung kami untuk menyimpan data. Kami ingin membuat tabel di pihak kami untuk menangani impor di masa depan serta apa yang ada dalam sampel. Tapi, baris-baris tertentu pasti akan lebih panjang, jadi kami pad mereka.

Pertanyaannya adalah berapa banyak, dan apakah ada pedoman teknis?


MongoDB menggunakan alokasi 2 ^ n disk untuk dokumen. SQL Server tidak menggunakan strategi ini.
Michael Green

Jawaban:


19

Terlepas dari tipe data tertentu, Anda harus dapat menyimpan apa pun permintaan aplikasi untuk disimpan. Anda tidak dapat menentukan sesuatu yang lebih kecil dari ukuran maksimum dari apa yang sebenarnya akan disimpan.

Anda juga tidak perlu, atau ingin, untuk menentukan panjang kolom lebih besar dari ukuran sebenarnya maksimum yang akan disimpan karena berbagai alasan: kueri alokasi memori, berpotensi mengisi ukuran baris maksimum dan tidak meninggalkan ruang untuk menambahkan kolom di masa depan, dll.

Benar, variabel panjang string dan kolom biner tidak memiliki implikasi penyimpanan yang tipe data panjang-tetap (string / binary / numeric / date / dll) lakukan (walaupun, beberapa implikasi tersebut dapat dibatalkan melalui kompresi data atau penggunaan SPARSEdefinisi kolom. pilihan). Namun, seperti yang Anda tunjukkan, bahkan jika tidak ada implikasi penyimpanan langsung, masih ada implikasi kinerja terlalu tinggi memori yang diperlukan untuk permintaan.

Masuk akal. Gunakan hanya apa yang Anda butuhkan. Pertimbangan dapat dibuat jika ada kemungkinan tinggi bahwa panjang kolom akan perlu meningkat dalam waktu dekat, tetapi perlu diingat bahwa lebih mudah untuk memperluas ukuran kolom daripada mengurangi ukuran. Ya, beberapa pekerjaan akan terlibat, tetapi karena pekerjaan itu hanya "potensial", sementara implikasi kinerja over-sizing adalah "aktual", seringkali lebih baik untuk mendefinisikan kolom berdasarkan pada apa yang sebenarnya Anda butuhkan, bukan apa yang Anda mungkin-agak -sorta pikir Anda mungkin perlu di masa depan. Banyak perubahan yang dibicarakan tidak pernah terjadi, dan seringkali perubahan yang diperlukan tidak dapat diramalkan. Pergilah dengan apa yang Anda ketahui.

Alih-alih, sasaran mungkin untuk membatasi ukuran aktual setiap baris data hingga ~ 8000 byte jika memungkinkan.

Saya tidak yakin apa yang Anda dapatkan di sini. SQL Server secara fisik akan membatasi Anda hingga lebih dari 8000 byte. Menggunakan jenis LOB - VARCHAR(MAX), NVARCHAR(MAX), VARBINARY(MAX), XML, dan usang TEXT, NTEXTdan IMAGEjenis - memungkinkan untuk melampaui bahwa pembatasan ukuran halaman awal, tapi itu hanya karena menempatkan pointer (16 atau lebih byte, tergantung pada jenis, dan tergantung pada ukuran nilai yang disimpan secara off-line saat menggunakan MAXtipe). Batas fisik sebenarnya dari halaman data tidak berubah.

Sasaran Anda adalah menggunakan ruang fisik paling sedikit untuk menyimpan apa yang dibutuhkan aplikasi / bisnis tanpa merusak atau memotong sehingga nilai yang tidak lengkap kehilangan makna atau menyebabkan masalah di hilir. Jika Anda perlu menyimpan 12.000 karakter, kemudian gunakan VARCHAR(MAX)karena itulah yang diperlukan. Jika Anda menyimpan nomor telepon atau kode pos, maka itu tidak bijaksana untuk digunakan VARCHAR(100), dan tidak bertanggung jawab untuk menggunakannya VARCHAR(MAX).

beberapa data pelanggan kami sedikit berfluktuasi, jadi kami biasanya membuat kolom sedikit lebih lebar dari yang seharusnya, katakanlah 15-20% lebih besar, untuk kolom tersebut. Saya bertanya-tanya apakah ada pertimbangan khusus lainnya;

Bukankah semua sistem memiliki setidaknya beberapa data yang berfluktuasi? Sistem apa pun yang menyimpan nama seseorang akan memenuhi syarat, bukan? Ada variasi yang cukup besar dalam panjang nama. Dan kemudian Anda memiliki seseorang seperti Pangeran pergi dan mengubah nama mereka menjadi simbol dan sekarang Anda memiliki masalah yang sama sekali berbeda yang tidak panjang. Begitulah keadaannya.

Tetapi, untuk berperan sebagai advokat iblis untuk sesaat: bagaimana mungkin nilai "15-20% lebih besar dari yang dibutuhkan" tidak menjadi nilai yang sebenarnya dibutuhkan ? Katakanlah ada diskusi tentang menambahkan kolom baru, dan seseorang menyarankan 50 karakter, lalu orang lain berkata, "20% lebih banyak adalah 60, jadi mari kita lakukan 60 karena seseorang mungkin memiliki 60." Jika benar bahwa pelanggan mungkin memiliki 60, maka 60 adalah, dan selalu, nilai yang sebenarnya dibutuhkan, dan 50 salah sepanjang waktu.

Tentu saja, akan membantu jika ada beberapa indikasi mengenai sumber data karena:

  1. jika Anda membuat "URL" 1024 dan seseorang membutuhkan 1060, maka itu harus 1060 (sama halnya, jika Anda membuat URL VARCHARdan mendapatkan keluhan bahwa itu mengacaukan karakter Unicode yang sekarang diizinkan dalam nama domain, maka itu harus NVARCHAR), tapi
  2. jika seseorang ingin menambahkan 1000 karakter ke bidang komentar batas-500 karakter, maka itu hanya perlu menjadi 500. Orang-orang dapat kurang bertele-tele dalam komentar (tantangan besar bagi saya ;-), tetapi ProductSKUlebih baik cukup besar untuk memenuhi semua SKU pelanggan.

Saya berbicara tentang pembuatan tabel awal. Seorang pelanggan akan memberi tahu kami bahwa mereka akan mulai mengirimkan kepada kami tabel baru, dan mengirimkan data sampel (atau hanya dataset produksi pertama), yang kami lihat dan buat tabel di ujung kami untuk menyimpan data. Kami ingin membuat tabel di pihak kami untuk menangani impor di masa depan serta apa yang ada dalam sampel. Tapi, baris-baris tertentu pasti akan lebih panjang, jadi kami pad mereka. Pertanyaannya adalah berapa banyak, dan apakah ada pedoman teknis?

Anda membuat banyak asumsi di sini. Tentu beberapa bidang mungkin menjadi lebih besar. Tetapi sekali lagi, mereka mungkin tidak. Atau, beberapa bisa menjadi lebih kecil. Beberapa dapat berubah dari non-Unicode menjadi Unicode (begitu mereka menyadari bahwa dunia semakin kecil dan orang tidak dapat berasumsi bahwa nama-nama terakhir hanya akan memiliki karakter ASCII / US English dasar). Atau, mereka bisa berhenti mengirim bidang. Atau mereka dapat menambahkan satu atau beberapa bidang di masa mendatang. Kombinasi apa pun dari ini dan hal-hal lain. Jadi mengapa hanya fokus pada VARCHARkolom? Bagaimana jika mereka saat ini mengirimkan INTnilai dan dalam satu atau dua tahun mereka mencapai nilai maksimal dan mulai mengirim nilai BIGINT? Bagaimana jika mereka memiliki bidang "status" dengan nilai 0 - 5. Apakah Anda hanya akan menganggapINTyang "empuk" karena memungkinkan untuk pertumbuhan, tetapi mungkin seharusnya TINYINT?

Satu-satunya hal yang dapat Anda prediksi dengan aman adalah mencoba memprediksi bagaimana data pelanggan Anda akan berubah lebih sering salah daripada benar. Dan menjadi benar adalah masalah keberuntungan / kebetulan (jika bukan keberuntungan, maka mainlah lotere;).

Jadi pedomannya adalah:

  1. Jangan buang waktu dan energi untuk mencoba menjawab pertanyaan yang tidak bisa dijawab.
  2. Alih-alih, fokuslah untuk mendapatkan sebanyak mungkin informasi mengenai data aktual pelanggan Anda, dan lakukan itu (yaitu pengambilan keputusan berdasarkan data ;-).

Anda sudah memiliki contoh data, bagus. Tetapi, jangan lupa bahwa Anda juga memiliki info kontak pelanggan Anda: telepon dan / atau email. Hubungi mereka! Tanyakan spesifikasi data mereka (seperti sistem Anda, data yang saat ini ada di sistem mereka mungkin memiliki panjang maksimal 35, tetapi sistem mereka menetapkannya sebagai VARCHAR(50), dan sistem mereka akan menerima hingga sejauh itu, dalam hal ini Anda harus menggunakan 50). Dan, tanyakan kepada mereka apakah mereka memiliki rencana jangka pendek untuk mengubah dan tipe-tipe data tersebut (tipe dan / atau ukuran).


1
Saya setuju dengan Solomon, @ Aristotle2600 - namun, Anda mungkin ingin melihat jawaban saya pada pertanyaan mengenai perbedaan antara a varchar(255)dan a varchar(256)untuk beberapa pertimbangan lebih lanjut
Max Vernon

Terima kasih, saya mendapat kesan bahwa ini akan menjadi sesuatu seperti ini, dan "hanya gunakan apa yang Anda butuhkan" hanyalah praktik manajemen sumber daya yang baik di mana-mana. Tetapi, beberapa data pelanggan kami sedikit berfluktuasi, jadi kami biasanya membuat kolom sedikit lebih lebar dari yang seharusnya, katakanlah 15-20% lebih besar, untuk kolom-kolom itu. Saya bertanya-tanya apakah ada pertimbangan khusus lainnya; misalnya, seseorang yang bekerja dengan saya mengatakan kepada saya untuk menggunakan 2 ^ n - 1 ukuran (saya belum menemukan bukti bahwa itu masalah ....). Tapi sepertinya tidak ada yang lain selain menjaga hal-hal sekecil mungkin.
aristotle2600

1
@ aristotle2600 Tidak yakin bagaimana menerapkan "2 ^ n - 1", tapi saya harus masih bertanya: apakah bahkan secara teoritis mungkin untuk membuat sesuatu yang lebih besar daripada kebutuhan untuk menjadi? Bukankah itu ukuran 15-20% lebih besar menjadi ukuran yang dibutuhkan untuk menjadi tidak istirahat? ;-). Saya yakin itu akan membantu jika Anda lebih eksplisit dalam sumber data, karena a) jika Anda membuat "URL" 1024 dan seseorang membutuhkan 1060, maka itu harus 1060, tetapi b) jika seseorang ingin menambahkan 1000 karakter ke kolom komentar 500-batas komentar, maka itu hanya perlu menjadi 500. Orang dapat memasukkan lebih sedikit dalam komentar, tetapi SKU produk lebih baik menjadi cukup besar.
Solomon Rutzky

@ aristotle2600 Saya baru saja menambahkan beberapa komentar Anda di sini ke pertanyaan karena memberikan konteks yang baik. Saya juga menambahkan hal-hal pada akhir jawaban saya :)
Solomon Rutzky

Terima kasih banyak atas jawaban Anda! Ya, nama dan alamat flucuate. Sejauh paradoks 20% yang terus meningkat, saya melihat apa yang Anda maksud, tapi saya berbicara tentang pembuatan tabel awal. Seorang pelanggan akan memberi tahu kami bahwa mereka akan mulai mengirimkan kepada kami tabel baru, dan mengirimkan data sampel (atau hanya dataset produksi pertama), yang kami lihat dan buat tabel di ujung kami untuk menyimpan data. Kami ingin membuat tabel di pihak kami untuk menangani impor di masa depan serta apa yang ada dalam sampel. Tapi, baris-baris tertentu pasti akan lebih panjang, jadi kami pad mereka. Pertanyaannya adalah berapa banyak, dan apakah ada pedoman teknis?
aristotle2600
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.