SQL'de VARCHAR üzerinden CHAR seçmek için kullanım durumları nelerdir?


270

Tüm değerlerim sabit genişlikteyse CHAR'ın önerildiğini anlıyorum. Ama ne olmuş yani? Neden sadece güvende olmak için tüm metin alanları için VARCHAR'ı seçmiyoruz?

Yanıtlar:


386

Genellikle tüm satırlar aynı uzunluğa yakınsa CHAR seçimini yapın . Seçim VARCHAR zaman uzunluğu değişkendir önemli. CHAR da tüm satırlar aynı uzunlukta olduğundan biraz daha hızlı olabilir.

DB uygulamasına göre değişir, ancak genellikle VARCHAR gerçek verilere ek olarak bir veya iki bayt daha fazla depolama alanı (uzunluk veya sonlandırma için) kullanır. Yani (bir baytlık karakter seti kullandığınızı varsayarak) "FooBar" kelimesini saklamak

  • CHAR (6) = 6 bayt (ek yük yok)
  • VARCHAR (10) = 8 bayt (2 bayt ek yük)
  • CHAR (10) = 10 bayt (4 bayt ek yük)

Alt satır CHAR nispeten aynı uzunlukta (iki karakter uzunluk farkı içinde) veriler için daha hızlı ve daha fazla yer verimli olabilir .

Not : Microsoft SQL'in VARCHAR için 2 bayt ek yükü vardır. Bu, DB'den DB'ye değişebilir, ancak genellikle bir VARCHAR'da uzunluğu veya EOL'yi belirtmek için en az 1 bayt ek yük gerekir.

Gaven tarafından yorumlarda belirtildiği gibi, UTF8 gibi çok baytlı, değişken uzunluklu bir karakter seti kullanıyorsanız, CHAR, karakter sayısını saklamak için gereken maksimum bayt sayısını saklar. UTF8'in bir karakteri saklamak için en fazla 3 bayta ihtiyacı varsa, CHAR (6) yalnızca latin1 karakterleri saklasa bile 18 bayta sabitlenecektir. Bu durumda VARCHAR çok daha iyi bir seçim haline gelir.


20
Başka bir neden de sayfa bölünmeleri ve parçalanmasıdır. Varchar sütunları sayfa bölmeleri nedeniyle% 99 parçalanmış bir IDEN PK ile bir tablo vardı. Çok aktif bir tablo ve uygulamanın doğası gereği yeni bir satır boş satır oluşturulur ve sonra doldurulur. Char parçalanma sorununu çözdü.
paparazzo

12
@Jim McKeeth - bu hesaplamalar yalnızca latin1 karakter seti kullanıyorsanız doğrudur. Çoğu insan bugünlerde utf8 kullanması gerektiğinden, CHAR sütunlarınız ortalama 3 kat boşluk kullanacak ve VARCHAR olarak temel çok dilli düzlemde çoğunlukla karakterleri saklayacaktır.
Gavin Towey

11
@JimMcKeeth evet, bu kesinlikle doğru. CHAR sabit uzunlukta olduğundan, kullanılabilecek maksimum boş alana sabitlenmelidir. UTF8'de bu karakter başına 3 bayt. Varchar için, karakter başına 1-3 bayt gerektiği gibi kullanmak ücretsizdir. Bu MySQL kılavuzundadır: dev.mysql.com/doc/refman/5.0/en/charset-unicode-utf8.html
Gavin Towey

3
FooBar ve varchar (100) vs char (100) dizesiyle arasındaki fark nedir? Bence bu farkı daha iyi gösteriyor, değil mi? Hayır?
Nenotlep

4
@GavinTowey SQLSERVER, NCHAR ve NVARCHAR veri türleri için UCS-2 kullanır. Karakter başına her zaman iki bayttır.
1010

69

Benimle çalışıyorsanız ve Oracle ile çalışıyorsanız, muhtemelen varcharneredeyse her koşulda sizi kullanırım . Daha charaz işlem gücü kullanan varsayım varchardoğru olabilir ... şimdilik ... ama veritabanı motorları zamanla daha iyi hale geliyor ve bu tür genel kural gelecekteki bir "efsane" yaratıyor.

Başka bir şey: Bir performans problemi hiç görmedim çünkü biri gitmeye karar verdi varchar. İyi kod (veritabanına daha az çağrı) ve verimli SQL (dizinler nasıl çalışır, optimize edici nasıl karar verir, neden genellikle existsdaha hızlıdır in) yazarak zamanınızı çok daha iyi kullanacaksınız .

Son düşünce: Kullanımıyla ilgili her türlü sorunu gördüm CHAR, '' aramaları gerektiğinde '' arayan insanlar '' veya 'FOO (burada bir sürü boşluk)' aramaları gerektiğinde 'FOO' arayan insanlar gördüm. veya sondaki boşlukları kırpmayan kişiler veya bir Oracle yordamından döndürdüğü değere 2000'e kadar boşluk ekleyen Powerbuilder'lı hatalar.


20
İlk paragrafınıza biraz katılmıyorum, çünkü char, optimizasyon yapanlara, hatta geleceğe yönelik olanlar için yararlı olabilecek bir ipucu verebilir ve sütunun amacını iletmeye yardımcı olabilir. Ancak üçüncü paragrafınız için +1. Tüm ekstra alanlardan nefret ediyorum. Bir alan, içine koyduğum her şeyi [açıklayıcı] dolgu olmadan depolamalıdır. Temel olarak, sadece tüm veriler tamamen aynı uzunlukta, daha fazla ve daha az, şimdi ve sonsuza dek olacaksa char kullanıyorum. Bu elbette çok nadirdir ve genellikle bir karakterdir (1).
Jeffrey L Whitledge

char da analistler ve geliştiriciler için bir ipucu sağlar ... bu şey x karakter sayısı .... Onlar başka bir biçimde serileştirme düşünüyorsanız, bu yararlı olabilir. (Ben uuid türü yoktu mssql bir karakter bir md5 sağlama toplamı saklamak zorunda kaldı ... ve ben hiç bir şey <32 bayt ... da sütun üzerinde bir kısıt koymak istemiyordu).
joefromct

31

Performans avantajlarına ek olarak CHAR, tüm değerlerin aynı uzunlukta olması gerektiğini göstermek için kullanılabilir , örneğin ABD eyalet kısaltmaları için bir sütun.


Veya ülke kodları - 2 veya 3 karakterlik ülke kodu kısaltması arasında ayrım yapmanıza yardımcı olabilir
Dan Field

Gerçekten sabit bir uzunluksa, bunu zorlayan bir kısıtlama olmalıdır. Her ne kadar kullanırsanız CHAR, kısıtlama dolgusu emin olun gerekir.
jpmc26

18

Char biraz daha hızlıdır, bu yüzden BİLİNECİĞİNİZ belli bir uzunlukta olacağınız bir sütun varsa, char kullanın. Örneğin, cinsiyet için bilinmeyen (M) ale / (F) emale / (U) veya bir ABD eyaleti için 2 karakter depolamak.


4
BÜYÜK bir cevap olduğundan emin değilim, çünkü bir ENUM genellikle çok daha mantıklı olurdu, ancak bu türün ne kadar yaygın olarak desteklendiğinden emin değilim (MySQL dışında).
Bobby Jack

Bana öyle geliyor ki, devletler kümesi değişmez olmak zorunda değil, bu yüzden char (2) bir enumdan çok daha uygun görünüyor.
Kearns

1
@Bobby Jack - Herhangi bir SQL numaralandırma uygulamasının belirli ayrıntılarını bilmiyorum, ancak 4 baytlık bir tamsayı olarak depolanan bir numaralandırmanın bir char (1) veya char (2) sütunundan daha fazla alan gerektirebileceğini unutmayın. aynı veri. Sekmelerin yorumlamaları açısından daha mantıklı olduğu ve bunun zorlayıcı olabileceği duygusu vardır, ancak RDBMS sistemindeki her şey bir düzeyde soyuttur ve tablolar için tanımlanan tahminlere tabidir.
Jeffrey L Whitledge

4
Kötü örnek, ENUM bu durumda en iyisidir. Daha iyi bir örnek, 3 harfli IATA havaalanı kodu
Andrew G. Johnson

5
@Andrew, tüm db'ler ENUM veri türlerini desteklemez. Örneğin, MSSQLServer bunu yapmaz. Ayrıca, int olarak saklanan bir ENUM 4 bayt alır. CHAR (1) 1 bayt alır ve NCHAR (1) 2 bayt alır.
Jarrett Meyer

17

NChar veya Char, var olan alternatiflerinden daha iyi performans gösteriyor mu?

Harika bir soru. Basit cevap bazı durumlarda evettir. Bakalım bu açıklanabilir mi?

Açıkçası hepimiz biliyoruz ki, bir varchar (255) sütunuyla bir tablo oluşturursam (bu sütunu myColumn olarak adlandırabiliriz) ve bir milyon satır eklerim, ancak her satır için myColumn'a sadece birkaç karakter koyarsak, tablonun çok daha küçük olacağını (genel olarak depolama motoru tarafından ihtiyaç duyulan veri sayfalarının sayısı) char (255) olarak myColumn'u oluşturduğumdan daha fazla. Ne zaman o tablo üzerinde bir işlem (DML) yapmak ve satır bir sürü talep, myColumn varchar olduğunda daha hızlı olacaktır çünkü sonunda tüm bu "ekstra" alanlarda hareket etmek zorunda değilsiniz . SQL Server'ın farklı veya birleşim işlemi gibi dahili türler yaptığı veya sorgu planı sırasında bir birleştirme seçtiği gibi olduğu gibi taşıyın.

Ancak varchar kullanımında bazı ek yükler var. SQL Server, her satırda, belirli bir satırın myColumn'unda kaç bayt olduğunu bilmek için iki baytlık bir gösterge (ek yük) kullanmalıdır. Sorunu sunan fazladan 2 bayt değil, her satırda myColumn'daki verilerin uzunluğunu "çözmek" zorunda.

Deneyimlerime göre, sorgularda birleştirilecek sütunlarda varchar yerine char kullanmak en mantıklı. Örneğin, tablonun birincil anahtarı veya dizine eklenecek başka bir sütun. Demografik tabloda CustomerNumber veya kod çözme tablosunda CodeID veya sipariş tablosunda belki OrderNumber. Char kullanarak, sorgu motoru sayfaları daha hızlı bir şekilde bayt taşımak yerine işaretçileri taşımak zorunda değilken düz pointer aritmetik (deterministik olarak) yapabileceği için birleştirme işlemini daha hızlı gerçekleştirebilir. Seni son cümle yüzünden kaybetmiş olabilirim. SQL Server'daki birleşimler "tahminler" fikrine dayanır. Bir yüklem bir durumdur. Örneğin, myColumn = 1 veya OrderNumber <500.

SQL Server bir DML deyimi gerçekleştiriyorsa ve birleştirilen tahminler veya "anahtarlar" sabit bir uzunluk (char) ise, sorgu motorunun bir tablodan satırlara eşleştirmek için çok fazla iş yapması gerekmez. başka bir tablo. Verilerin satırda ne kadar süre kaldığını bulup sonunu bulmak için dizeden aşağı inmek zorunda kalmayacak. Tüm bunlar zaman alır.

Şimdi bunun kolayca kötü bir şekilde uygulanabileceğini unutmayın. Çevrimiçi sistemlerde birincil anahtar alanlar için kullanılan char gördüm. Genişlik küçük tutulmalıdır, yani char (15) veya makul bir şey. Çevrimiçi sistemlerde en iyi sonucu verir, çünkü genellikle yalnızca az sayıda satırı alır veya üzeresiniz, bu nedenle sonuç kümesinde alacağınız sondaki boşlukları "rtrim" etmek, milyonlarca gruba katılmak yerine önemsiz bir görevdir. bir tablodan başka bir tablodaki milyonlarca satıra kadar sıralar.

CHAR'ın çevrimiçi sistemlerde varchar üzerinde anlamlı olmasının bir başka nedeni de sayfa bölünmelerini azaltmasıdır. Char kullanarak, aslında bu alanı "ayırır" (ve israf), böylece bir kullanıcı daha sonra gelir ve bu sütuna daha fazla veri koyarsa SQL zaten onun için boşluk ayırdı ve gidiyor.

CHAR'ı kullanmanın bir başka nedeni de ikinci nedene benzer. Bir programcı veya kullanıcı, örneğin bir not alanına bir cümle ekleyerek milyonlarca satıra "toplu" bir güncelleme yaparsa, gece yarısı DBA'nızdan sürücülerinin neden dolu olduğunu merak eden bir çağrı almayacaksınız. Başka bir deyişle, bir veritabanı boyutunun daha öngörülebilir büyümesine yol açar.

Yani bunlar bir çevrimiçi (OLTP) sisteminin varchar üzerinden chartan yararlanabilmesinin 3 yoludur. Ben genellikle bir depo / analiz / OLAP senaryosunda char kullanıyorum çünkü genellikle tüm bu sütunların çok fazla boşa alan ekleyebileceği çok fazla veri var.

Char'ın veritabanınızı çok daha büyük hale getirebileceğini, ancak çoğu yedekleme aracının veri sıkıştırma özelliğine sahip olduğunu, bu nedenle yedeklemelerinizin varchar kullanmış olduğunuzla aynı boyutta olma eğiliminde olduğunu unutmayın. Örneğin LiteSpeed ​​veya RedGate SQL Yedekleme.

Başka bir kullanım, verileri sabit genişlikli bir dosyaya aktarmak için oluşturulan görünümlerdir. Diyelim ki bir ana bilgisayar tarafından okunmak için bazı verileri düz bir dosyaya vermeliyim. Sabit genişliktedir (sınırlandırılmamıştır). Verileri "aşamalandırma" tablomda varchar (böylece veritabanımda daha az yer kaplar) depolamak ve daha sonra bu sütun için sabit genişlik genişliğine karşılık gelen uzunluğu ile eşdeğer her şeyi CAST için bir görünüm kullanmak istiyorum . Örneğin:

create table tblStagingTable (
pkID BIGINT (IDENTITY,1,1),
CustomerFirstName varchar(30),
CustomerLastName varchar(30),
CustomerCityStateZip varchar(100),
CustomerCurrentBalance money )

insert into tblStagingTable
(CustomerFirstName,CustomerLastName, CustomerCityStateZip) ('Joe','Blow','123 Main St Washington, MD 12345', 123.45)

create view vwStagingTable AS
SELECT CustomerFirstName = CAST(CustomerFirstName as CHAR(30)),
CustomerLastName = CAST(CustomerLastName as CHAR(30)),
CustomerCityStateZip = CAST(CustomerCityStateZip as CHAR(100)),
CustomerCurrentBalance = CAST(CAST(CustomerCurrentBalance as NUMERIC(9,2)) AS CHAR(10))

SELECT * from vwStagingTable

Bu harika çünkü verilerim dahili olarak daha az yer kaplıyor çünkü varchar kullanıyor. Ancak DTS veya SSIS kullandığımda, hatta SSMS'den Not Defteri'ne yalnızca bir kesip yapıştırdığımda, görünümü kullanabilir ve doğru sayıda arka boşluk elde edebilirim. DTS'de eskiden bir özelliğimiz vardı, lanet olsun ki "sütunları öner" ya da başka bir şey olduğunu düşünüyorum. SSIS'de artık bunu yapamazsınız, düz dosya bağlantı yöneticisini sıkıcı bir şekilde tanımlamanız gerekir. Ancak görünüm ayarlarınızı yaptığınızdan, SSIS her bir sütunun genişliğini bilebilir ve veri akışı görevlerinizi oluştururken çok zaman kazandırabilir.

Sonuç olarak ... varchar kullanın. Char'ı kullanmak için çok az sayıda neden vardır ve bu yalnızca performans nedenleriyle ortaya çıkar. Milyonlarca satır hundrends'lı bir sisteminiz varsa, tahminler deterministik (char) ise, ancak char kullanan çoğu sistem için sadece alan israf ediyorsa fark edilir bir fark göreceksiniz.

Umarım yardımcı olur. Jeff


Sabit sohbetin sadece depolandığında değil, aynı zamanda söylediğiniz gibi taşındığında veya taşındığında da daha fazla yer kapladığını mı söylüyorsunuz? DB Server'dan istemcime örneğin? Bu boş baytları ne zaman kaybederiz?
Kırmızı Bezelye

9

Performans avantajları var, ancak burada belirtilmeyen bir fayda var: satır göçü. Char ile tüm alanı önceden ayırırsınız. Diyelim ki bir karakteriniz var (1000) ve 10 karakter saklıyorsunuz, 1000 karakter alanınızı kullanacaksınız. Bir varchar2'de (1000) yalnızca 10 karakter kullanırsınız. Verileri değiştirdiğinizde sorun ortaya çıkar. Sütunu şimdi 900 karakter içerecek şekilde güncellediğinizi varsayalım. Varchar'ı genişletecek alanın mevcut blokta mevcut olmaması mümkündür. Bu durumda, DB motoru satırı başka bir bloğa geçirmeli ve orijinal blokta yeni bloktaki yeni satıra bir işaretçi yapmalıdır. Bu verileri okumak için, DB motorunun şimdi 2 bloğu okuması gerekecektir.
Hiç kimse varchar veya char'ın daha iyi olduğunu açıkça söyleyemez. Zaman aşımı için bir alan vardır ve özellikle de büyümesi için iyi bir şans varsa, verilerin güncellenip güncellenmeyeceğini düşünün.


Bence yazında bir yazım hatası var - varchar2 (1000) CHAR (1000) olmamalı mı?
Matt Rogish

8

Erken performans optimizasyonu ile en iyi uygulama kuralı kullanmak arasında bir fark vardır. Her zaman sabit uzunluklu bir alana sahip olacağınız yeni tablolar oluşturuyorsanız, CHAR kullanmak mantıklıdır, bu durumda kullanmalısınız. Bu erken optimizasyon değil, daha çok bir kural (veya en iyi uygulama) uygulamak.

ie - 2 harfli durum alanınız varsa, CHAR (2) kullanın. Gerçek durum adlarına sahip bir alanınız varsa, VARCHAR'ı kullanın.


8

Sütun her zaman 2 karakter uzunluğunda ve geçerli ABD devletleri kodu listesi sık sık değişmez :) ABD devlet kodu gibi sabit bir değer depolamak sürece varchar seçerim :).

Diğer her durumda, karma parolayı (sabit uzunluklu) depolamak gibi, varchar'ı seçerdim.

Neden - char tipi sütun her zaman boşluklarla yerine getirilir; bu, karşılaştırma içinde 'ABC' değeriyle char (5) olarak tanımlanan my_column sütununu yapar :

my_column = 'ABC' -- my_column stores 'ABC  ' value which is different then 'ABC'

yanlış.

Bu özellik geliştirme sırasında birçok rahatsız edici hataya neden olabilir ve testi zorlaştırır.


1
En azından MSSQL Sunucusunda 'abc' = 'abc'. Bu özelliği beğenirim ya da beğenmezsem asla anlayamadım ....
Mark Brackett

Burada char doldurma hakkında iyi bir okuma Padding
Edward

6

Bu alandaki tüm veri değerleriniz aynı uzunlukta ise CHAR, VARCHAR'dan daha az depolama alanı kaplar. Şimdi belki de 2009'da 800GB veritabanı tüm hedefler ve amaçlar için aynıdır, eğer VARCHAR'ları CHAR'lara dönüştürdüyseniz, ancak kısa dizeler (1 veya 2 karakter) için CHAR hala bir endüstri "en iyi uygulaması" diyorum.

Şimdi, çoğu veritabanının yalnızca tamsayılar (bit, tiny, int, bigint) için bile sağladığı çok çeşitli veri türlerine bakarsanız, birini diğerinden seçmek için nedenler vardır. Her seferinde bigint'i seçmek aslında alanın amaçlarından ve kullanımlarından biraz habersizdir. Bir tarla sadece yaşları olan bir kişiyi temsil ediyorsa, bigint aşırıya kaçar. Şimdi mutlaka "yanlış" değil, ama etkili değil.

Ancak bu ilginç bir argüman ve veritabanları zaman içinde geliştikçe CHAR vs VARCHAR'ın daha az alakalı hale geldiği iddia edilebilir.


4

Jim McKeeth'in yorumunun yanındayım.

Ayrıca, tablonuzda yalnızca CHAR sütunları varsa dizin oluşturma ve tam tablo taramaları daha hızlıdır. Temel olarak optimizer, her bir kaydın yalnızca CHAR sütunları varsa ne kadar büyük olduğunu tahmin edebilecekken, her VARCHAR sütununun boyut değerini kontrol etmesi gerekir.

Ayrıca, bir VARCHAR sütununu önceki içeriğinden daha büyük bir boyuta güncellerseniz, veritabanını dizinlerini yeniden oluşturmaya zorlayabilirsiniz (çünkü veritabanını diskteki kaydı fiziksel olarak taşımak zorunda kaldınız). CHAR sütunları ile asla olmayacak.

Ancak, tablonuz büyük olmadıkça muhtemelen performans isabetini umursamazsınız.

Djikstra'nın akıllı sözlerini hatırla. Erken performans optimizasyonu tüm kötülüklerin köküdür.


4
Yorumunuzda bir miktar spekülasyon var. Bunun gibi varsayımların tekrar tekrar test edildiğini ve tam tersinin doğru olduğunu gördüm. Sorun birçok mühendisin müjde olarak böyle bilgi almasıdır. Lütfen dostlar, gerçek durumlarınızı yansıtan test senaryoları oluşturun.
Ethan Post

Ethan tamamen doğru. Bu, kullandığınız uygulamaya bağlıdır, gerçek (Ürün, Sürüm) referansları olmadan tamamen işe yaramaz.
David Schmitt

Bir CHARsütunu güncellediğinizde , dizinlerin de güncellenmesi gerekir. Bu bağlamda bir VARCHAR veya CHAR sütununu güncellemede bir fark yoktur. Güncellenmesi düşünün FOOiçin BAR.
a_horse_with_no_name

4

Birçok kişi, CHAR kullanarak değerin tam uzunluğunu biliyorsanız bazı faydalara sahip olduğuna dikkat çekmiştir. Ancak ABD eyaletlerini CHAR (2) olarak depolamak bugün harika olsa da, satışlardan 'Avustralya'ya ilk satışımızı yaptık' mesajını aldığınızda, acı dünyasındasınız. Gelecekteki olayları kapsamak için 'kesin' bir tahmin yapmak yerine alanların ne kadar süreceğini düşündüğümü her zaman tahmin etmek için gönderirim. VARCHAR bana bu alanda daha fazla esneklik sağlayacak.


3

Sanırım senin durumunda Varchar'ı seçmemek için hiçbir sebep yok. Size esneklik sağlar ve bir dizi katılımcı tarafından belirtildiği gibi, performans şimdi çok spesifik koşullar dışında (Google DBA'ların aksine) daha fazla fark yaratmayacak.

DB Türleri söz konusu olduğunda dikkat çeken ilginç bir şey, sqlite (oldukça etkileyici performansa sahip popüler bir mini veritabanı) her şeyi veritabanına bir dize ve türler olarak koyar.

Her zaman VarChar kullanıyorum ve genellikle ihtiyacım olandan çok daha büyük yapıyorum. Örneğin. 50 Neden First Name için, neden sadece güvenli olmak değil.


3

ASLA karakter kullanmam. Birçok insanla bu tartışmayı yaşadım ve her zaman char'ın daha hızlı olduğu yorgun klişeyi ortaya çıkarırlar. Peki, ne kadar hızlı? Burada neden bahsediyoruz, milisaniye, saniye ve eğer öyleyse kaç tane? Bana söylüyorsun çünkü birisi birkaç milisaniyeden daha hızlı olduğunu iddia ediyor, sisteme tonlarca düzeltilmesi zor hatalar getirmeliyiz?

İşte size karşılaşacağınız bazı sorunlar:

Her alan dolgulu olacak, böylece sonsuza kadar her yerde RTRIMS olan bir kodla karşılaşacaksınız. Bu aynı zamanda uzun alanlar için büyük bir disk alanı israfıdır.

Şimdi diyelim ki sadece bir karakterlik bir char alanının özlü bir örneğine sahipsiniz ancak alan isteğe bağlıdır. Birisi bu alana boş bir dize geçirirse, bir boşluk haline gelir. Başka bir uygulama / işlem sorguladığında, rtrim kullanmazlarsa tek bir alan alırlar. İsteğe bağlı alanlarda xml dokümanlarımız, dosyalarımız ve diğer programlarımız var, yalnızca bir alan gösterdik ve bir şeyler kırdık.

Bu yüzden şimdi boş alana değil, boş karakterleri char alanına geçirdiğinizden emin olmalısınız. Ancak bu null değerinin doğru kullanımı DEĞİLDİR. İşte null kullanımı. Diyelim ki bir satıcıdan dosya alıyorsunuz

Ad | Cinsiyet | Şehir

Bob || Los Angeles

Bob girdiğinizden cinsiyet belirtilmezse, tabloya boş dize ve Los Angeles yazın. Şimdi dosyayı alacağınızı ve dosya biçiminin değiştiğini ve cinsiyetin artık dahil olmadığını ancak geçmişte olduğunu varsayalım.

Ad | Şehir

Bob | Seattle

Şimdi cinsiyet dahil olmadığından, null kullanacağım. Varchars bunu sorunsuz bir şekilde desteklemektedir.

Öte yandan Char farklıdır. Her zaman null göndermeniz gerekir. Hiç boş dize gönderirseniz, içinde boşluk bulunan bir alanla karşılaşırsınız.

Ben chars ve yaklaşık 20 yıllık gelişme düzeltmek zorunda kaldım tüm hatalar ile devam ve devam.


2

Bir sütun değeri için gereken gerçek boyutun hesaplanmasında ve bir Varchar için alan tahsis edilmesinde küçük bir işlem yükü vardır, bu nedenle değerin her zaman ne kadar uzun olacağından kesinlikle eminseniz, Char'ı kullanmak ve isabetten kaçınmak daha iyidir.


2

Performans dengesine karşı klasik alan.

MS SQL 2005'te Varchar (veya karakter başına iki bayt, yani Çince için gereken baytlar için NVarchar) değişken uzunluktadır. Sabit diske yazıldıktan sonra satıra eklerseniz, verileri orijinal satıra uygun olmayan bir konumda bulur ve veri dosyalarınızın parçalanmasına neden olur. Bu performansı etkileyecektir.

Bu yüzden, alan bir sorun değilse, Char performans için daha iyidir, ancak veritabanı boyutunu düşük tutmak istiyorsanız varchars daha iyidir.


2

Parçalanma. Char yer ayırır ve VarChar bunu yapmaz. Varchar güncellemesine uyum sağlamak için sayfa bölünmesi gerekebilir.


Diğer birçok faktörden dolayı, bir CHARsütun güncellenirken sayfa bölünmesi meydana gelebilir .
Rick James

1

varchar değerleri kullanırken SQL Server, bu sütun hakkında bazı bilgileri depolamak için satır başına ek 2 bayta ihtiyaç duyarken, char kullanırsanız,


0

Bazı SQL veritabanlarında, VARCHAR ofsetleri optimize etmek için maksimum boyutuna kadar doldurulur, Bu tam tablo taramalarını ve dizinleri hızlandırmak içindir.

Bu nedenle, bir CHAR (200) ile karşılaştırıldığında bir VARCHAR (200) kullanarak yerden tasarruf edemezsiniz


3
Hangi veritabanları VARCHAR'ı bu şekilde uygular?
Troels Arvin

5
Cidden, hangi veritabanı onu bu şekilde uygular? Açıkladığınız şey normalde VARCHAR için değil CHAR için geçerlidir.
Richard Simões

mysql, aynı tabloda char ve varchar'lar varsa varchar'ları charlara dönüştürür.
Malfist

MySQL yorumlarımın yorumlanması, bunun birincil tablo depolaması için geçerli olmadığı, ancak geçici tablolar için alakalı olabileceği yönündedir. verileri gruplamak / sıralamak için. dev.mysql.com/doc/refman/8.0/en/char.html stackoverflow.com/questions/262238/…
Thomas W

0

CHAR (NCHAR) ve VARCHAR (NVARCHAR) kullanmak, veritabanı sunucusunun verileri depolama biçiminde farklılıklar getirir. Birincisi sondaki boşlukları tanıtır; SQL SERVER işlevlerinde LIKE operatörü ile kullanırken sorunla karşılaştım. Bu yüzden her zaman VARCHAR (NVARCHAR) kullanarak güvenli hale getirmem gerekiyor.

Örneğin, bir TEST (ID INT, Status CHAR (1)) tablonuz varsa ve aşağıdaki gibi belirli bir değere sahip tüm kayıtları listelemek için bir işlev yazarsanız:

CREATE FUNCTION List(@Status AS CHAR(1) = '')
RETURNS TABLE
AS
RETURN
SELECT * FROM TEST
WHERE Status LIKE '%' + @Status '%'

Bu işlevde, varsayılan parametreyi koyduğumuzda işlevin tüm satırları döndürmesini bekleriz, ancak aslında geri dönmez. @Status veri türünü VARCHAR olarak değiştirmek sorunu çözecektir.


Bu, ansi_padding ile de değiştirilebilir. Değerler nasıl alınır
Edward
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.