MySQL VARCHAR ve TEXT veri türleri arasındaki fark nedir?


19

Sürüm 5.0.3'ten sonra (VARCHAR'ın 65.535 bayt olmasına izin veren ve kesilen arka boşlukları durdurdu), bu iki veri türü arasında büyük bir fark var mı?

Farklılıklar listesini okuyordum ve sadece iki not:

BLOB ve TEXT sütunlarındaki dizinler için bir dizin önek uzunluğu belirtmelisiniz. CHAR ve VARCHAR için önek uzunluğu isteğe bağlıdır. Bkz. Bölüm 7.5.1, “Sütun Endeksleri”.

ve

BLOB ve TEXT sütunlarında VARSAYILAN değerleri olamaz.

Öyleyse, METİN veri tipindeki bu iki sınırlama nedeniyle, neden varchar (65535) üzerinde kullanıyorsunuz? Birinin diğerine göre performans sonuçları var mı?


1
Verilerde 65535 karakterden fazla olmasını istediğinizde?
BlackICE

İşte varchar ve metin arasındaki karşılaştırmalar hakkında oldukça iyi bir forum dizisi: http://forums.mysql.com/read.php?24,105964,105964
bölünmüş

Buradaki liste gerçekten açık detayları ortaya koymak için iyi bir iş çıkardığından ve zaten numaralandırılmış farklılıklar listesine sahip olduğunuzdan, bunun DBA'da ihtiyacımız olan bir soru olduğundan emin değilim. Belirttiğiniz listenin ve verdiğiniz nedenlerin bu durumda yeterince iyi olmaması için bir neden var mı? Aksi takdirde VtC'ye gidiyorum
jcolebrand

1
Sorumu güncelledim, ancak emin olmadığım en açık nedenlerden biri diğerinin performansıdır. Çok açık olmayan başka nedenler olup olmadığından emin değilim
Derek Downey

Öyleyse, sorduğunuz şeyin diğerinin performans özellikleri olması adil mi?
jcolebrand

Yanıtlar:


13

bölünmesiyle temel sorunu açıklar bazı bilgi ile bağlantılı (orada performans farklılıklarını var), ama bir her zaman daha iyi diğerinden daha olduğunu söylemek basit yeterli değil. (aksi takdirde, her ikisine birden sahip olmanız için bir neden yoktur.) Ayrıca, MyISM'de, VARCHAR için maksimum 64k boyut alan başına değildir - kayıt başınadır.

Temel olarak, dizeleri veritabanı kayıtlarında saklamanın 4 yolu vardır:

  1. sabit uzunluk
  2. C stili dizeler (dizenin sonunda NULL veya benzeri bir karakterle işaretlenmiştir)
  3. Pascal tarzı dizeler (uzunluğu belirtmek için birkaç bayt, sonra dize)
  4. İşaretçiler (dizeyi başka bir yerde saklayın)

MyISM, VARCHAR için # 3'e benzer bir şey ve TEXT için dizenin başlangıcını kayıtta, ardından dizenin geri kalanını başka bir yerde sakladığı karma bir yaklaşım kullanır. InnoDB, VARCHAR için benzerdir, ancak METİN alanının tamamını kayıt dışında saklar.

1 ve 4 ile, kayıttaki şeyler her zaman aynı uzunluktadır, bu nedenle dizeye ihtiyacınız yoksa, ancak ondan sonra bir şeylere ihtiyacınız varsa atlamak daha kolaydır. Hem # 2 hem de # 3 kısa dizeler için çok kötü değil ... # 2 işaretleyiciyi aramaya devam ederken, # 3 ileri atlayabilir ... dizeler uzadıkça # 2 bu özel kullanım için daha da kötüleşir durum.

Dizeyi gerçekten okumanız gerekiyorsa, kaydı okumak zorunda olduğunuzdan # 4 daha yavaştır, daha sonra veritabanının nasıl işlediğine bağlı olarak diskte başka bir yerde depolanabilecek dizeyi okuyun. # 1 her zaman oldukça basittir ve yine # 2 için dize uzadıkça benzer sorunlarla karşılaşırsınız, # 3 çok küçük dizeler için # 2'den biraz daha kötüdür, ancak daha uzun olduğu için daha iyidir.

Daha sonra depolama gereksinimleri var ... # 1 her zaman sabit bir uzunluktur, bu nedenle çoğu dize maksimum uzunluk değilse şişebilir. # 2 1 ekstra bayta sahiptir; # 3 genellikle maksimum uzunluk = 255 ise 2 ekstra bayta, 64 k maks. # 4, işaretçi uzunluğuna ve tipik olarak # 3 için kurallara sahiptir.

MySQL 5.1 içindeki belirli uygulamalar için, MyISM dokümanları şunları belirtir :

  • Gerçek bir VARCHAR türü için destek; VARCHAR sütunu, bir veya iki baytta saklanan bir uzunlukla başlar.
  • VARCHAR sütunlarına sahip tabloların sabit veya dinamik satır uzunluğu olabilir.
  • Bir tablodaki VARCHAR ve CHAR sütunlarının uzunluklarının toplamı 64 KB'a kadar olabilir.

InnoDB için iken :

  • Kayıt başlığının değişken uzunluktaki kısmı, NULL sütunları belirtmek için bir bit vektörü içerir. Dizinde NULL olabilecek sütun sayısı N ise, bit vektörü CEILING (N / 8) baytını işgal eder. (Örneğin, NULL olabilen 9 ila 15 sütun arasında herhangi bir yer varsa, bit vektörü iki bayt kullanır.) NULL olan sütunlar, bu vektördeki bit dışında bir alan işgal etmez. Üstbilginin değişken uzunluktaki kısmı, değişken uzunluktaki sütunların uzunluklarını da içerir. Her uzunluk, sütunun maksimum uzunluğuna bağlı olarak bir veya iki bayt alır. Dizindeki tüm sütunlar BOŞ DEĞİLDİR ve sabit bir uzunluğa sahipse, kayıt üstbilgisinde değişken uzunluklu bir parça yoktur.
  • Her NULL olmayan değişken uzunluklu alan için, kayıt üstbilgisi bir veya iki bayttaki sütunun uzunluğunu içerir. Sütunun bir kısmı taşma sayfalarında harici olarak depolanıyorsa veya maksimum uzunluk 255 baytı aşarsa ve gerçek uzunluk 127 baytı aşarsa iki bayt gerekir. Harici olarak saklanan bir sütun için, iki baytlık uzunluk dahili olarak depolanan parçanın uzunluğunu ve harici olarak depolanan parçaya 20 baytlık işaretçiyi belirtir. İç kısım 768 bayttır, bu nedenle uzunluk 768 + 20'dir. 20 baytlık işaretçi sütunun gerçek uzunluğunu saklar.

...

veritabanlarıyla uğraşırken diğer pek çok şeyde olduğu gibi, ihtiyaçlarınız için en iyi olandan emin değilseniz, benzer veriler ve kullanımla karşılaştırmayı deneyin ve nasıl davrandıklarını görün.


İş parçacığı, MySQL'in blokları ve metin alanlarını satır içi forums.mysql.com/read.php?24,105964,267596#msg-267596
Michael

1
Nitpick ... Tüm pratik amaçlar için, her iki Motorda da bir satırda 64 KB sınır yoktur. LONGTEXTve LONGBLOBbuna bir örnektir. C tarzı dizeler MySQL (bildiğim) tarafından hiçbir yerde kullanılmaz. InnoDB bir 'karma' yaklaşım kullanır, ancak satır boyutuna, satır biçimine vb. Bağlı olarak daha karmaşıktır. Dizeleri "sabit" uzunlukta saklamak, sabit bir uzunluk (country_code, zip_code, vb.) Dışında neredeyse hiçbir zaman önerilmez. . InnoDB'de 4 ROW_FORMATs; metin bunlardan sadece 1 veya 2'sini tartışıyor.
Rick James

2

Bir SELECT'in geçici bir tablo oluşturması gerektiğinde (sonuçları sıralamak gibi), bir MEMORY tablosu veya bir MyISAM tablosu oluşturur. BELLEK daha verimlidir. BELLEK üzerinde kısıtlamalar var - biri METİN ve BLOB'a izin vermemek. Bu nedenle, SELECT , TEXT ile VARCHAR'dan daha yavaş çalışabilir.

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.