Raylardaki dize ve metin arasındaki fark nedir?


435

Rails kullanarak yeni bir web uygulaması yapıyorum ve merak ediyorum stringve arasındaki fark textnedir? Ve her biri ne zaman kullanılmalıdır?

Yanıtlar:


522

Fark, sembolün sorgu dilinde ilgili sütun türüne nasıl dönüştürüleceğine dayanır.

MySQL ile: string VARCHAR (255) ile eşlenir - http://guides.rubyonrails.org/migrations.html

:string |                   VARCHAR                | :limit => 1 to 255 (default = 255)  
:text   | TINYTEXT, TEXT, MEDIUMTEXT, or LONGTEXT2 | :limit => 1 to 4294967296 (default = 65536)

Referans:

http://www.packtpub.com/article/Working-with-Rails-ActiveRecord-Migrations-Models-Scaffolding-and-Database-Completion

Her biri ne zaman kullanılmalıdır?

Genel bir kural olarak, :stringkısa metin girişi (kullanıcı adı, e-posta, şifre, başlıklar vb.) İçin kullanın ve :textaçıklamalar, yorum içeriği vb. Gibi daha uzun süre beklenen girdiler için kullanın .


11
Bence daha iyi bir kural her zaman kullanmaktır :text. Bkz. Depesz.com/2010/03/02/charx-vs-varcharx-vs-varchar-vs-text
Reed G. Law

74
MySQL için - çok değil, varchars üzerinde dizinleriniz olabilir, metin üzerinde olamaz.
Omar Qureshi

12
PostgreSQL uygulaması metni tercih eder. Pg string / text için tek fark string için uzunluk kısıtlamasıdır. Performans farkı yok.
Andy Bettisworth

Bu, ActiveRecord ile hikayenin tamamı gibi görünmüyor. Değeri trueMySQL'de bir varchar'a (ergo, stringtip alanı) kaydetmek, değeri seri hale getirir 1(ki bu tamamen adil). Ancak, texttip altında , "true" değerinin saklanması, bu değeri tekil bir karakter olarak serileştirir t. Bunu ve değerin doğru olduğu gelecekteki tüm satırları şimdi fark etmeden bir sütun taşıdım t. Herkes bu davranış hakkında herhangi bir görüş var mı?
Peter

1
@ elli0t, dizine ekleyemeyeceğiniz anlamına gelir. Bu önemliyse, MySQL üzerinde metin kullanmamalısınız
Omar Qureshi

157

Postgres kullanıyorsanız, metin için performans cezası olmadığı için boyut sınırlaması olmadığı sürece boyut kısıtlamanız olmadığı sürece mümkün olan her yerde metin kullanın

Bu üç tür arasında, boş dolgulu türü kullanırken artan depolama alanı ve uzunluk kısıtlı bir sütuna depolarken uzunluğu kontrol etmek için birkaç ekstra CPU döngüsü dışında hiçbir performans farkı yoktur. Karakter (n) diğer bazı veritabanı sistemlerinde performans avantajlarına sahip olsa da, PostgreSQL'de böyle bir avantaj yoktur; aslında karakter (n) ek depolama maliyetleri nedeniyle genellikle üçün en yavaş olanıdır. Çoğu durumda metin veya karakter değiştirme kullanılmalıdır.

PostsgreSQL kılavuzu


4
Ama veritabanı agnostik olma yararına, bu en iyi yaklaşım mı? Veritabanını değiştirmek isterseniz ne olur? Gerçek dünyada bu sık sık gerçekleşmeyen, ama yine de ... 'performans farkı' yoksa, neden kısa şeyler için ipin ve daha uzun şeyler için metinlerin beklenen kullanımına bağlı kalmıyorum? Ve kendi yorum dizine ekleme dizeleriniz göz önüne alındığında, hala en iyi yaklaşım gibi görünüyor.
Dan Barron

6
Herhangi bir soruna Tek Doğru Çözüm olduğu fikrini atmanın en iyi olduğu Gerçek Dünya'da gerekli olmasının birçok nedeni vardır.
Dan Barron

14
Öyle olabilir, ama veritabanı agnostisizm sahte bir peygamberdir.
Omar Qureshi

2
Performans cezasının önemli olup olmadığı hakkında herhangi bir bilgisi olan var mı yoksa bu erken bir optimizasyon örneği mi? Tahminimce, paragrafın açılmasının onayladığı bir fark görmeyeceksiniz: "Bu üç tip arasında performans farkı yok".
Dennis

5
İyi bir noktaya değindin, ama tamamen ikna olmadım. Kullandığınızda söz konusu blog yazısında argümanlar textüzerinde (n)veri türlerini ikna, ancak kullanımı için argüman textüzerinde varchardeğildir. Aynı olduklarını söyler, ancak tercih edilebilir textçünkü varcharkarıştırılabilir varchar(n)ve yazılması textdaha az karakterdir. Ancak textbunun yerine kullanarak varchar, saklanan verilerin uzun olmaması gerektiği bağlamını kaybedersiniz. Örneğin, bir kullanıcı adının saklanması textbenim için yanıltıcı görünüyor.
Dennis

17

Dize, veritabanınızda "Varchar", metin ise "metin" anlamına gelir. Bir varchar çok daha az öğe içerebilir, bir metin (neredeyse) herhangi bir uzunlukta olabilir.

İyi referanslarla derinlemesine analiz için http://www.pythian.com/news/7129/text-vs-varchar/ adresini ziyaret edin.

Düzenleme: Bazı veritabanı motorları varchartek seferde yükleyebilirsiniz , ancak tablonun dışında metin (ve blob) depolayabilirsiniz. Bir SELECT name, amount FROM productskullanırken, çok daha yavaş olabilir textiçin namekullandığınızda daha varchar. Ve Rails, varsayılan olarak SELECT * FROM...metin sütunları ile kayıtları yükler yüklenir. Bu muhtemelen sizin veya uygulamanızda gerçek bir sorun olmayacaktır (Erken optimizasyon ...). Ancak metnin her zaman "özgür" olmadığını bilmek iyi bir şeydir.


12

Boyut sabit ve küçükse dize ve değişken ve büyükse metin. Bu biraz önemlidir çünkü metin dizelerden çok daha büyüktür. Çok daha fazla kilobayt içerir.

Yani küçük alanlar için her zaman string (varchar) kullanın. Alanlar gibi. ad, giriş, e-posta, konu (bir makalenin veya yayının) ve metin örnekleri: bir yayının veya makalenin içeriği / gövdesi. paragraf alanları vb.

Dize boyutu 1 ila 255 (varsayılan = 255)

Metin boyutu 1 - 4294967296 (varsayılan = 65536) 2


11

Yukarıda açıklandığı gibi sadece db veri türü değil, aynı zamanda iskele olursanız oluşturulacak görünümü de etkileyecektir. dize bir text_field metni oluşturur text_area üretir


2

Adlar, adres, telefon, şirket gibi daha kısa alanlar için dize kullanın

Daha büyük içerik, yorumlar, içerik, paragraflar için Metin kullanın.

Genel kuralım, birden fazla satır olan bir şeyse, genellikle metin için gidiyorum, eğer 2-6 kelimelik kısa bir kelime ise, dize için gidiyorum.

Bir dize için resmi kural 255'tir. Dizeniz 255 karakterden fazlaysa metin için gidin.


1

Eğer kahini kullanıyorsanız ... STRINGolarak oluşturulacak VARCHAR(255)sütunda ve TEXTbir şekilde, CLOB.

NATIVE_DATABASE_TYPES = {
    primary_key: "NUMBER(38) NOT NULL PRIMARY KEY",
    string: { name: "VARCHAR2", limit: 255 },
    text: { name: "CLOB" },
    ntext: { name: "NCLOB" },
    integer: { name: "NUMBER", limit: 38 },
    float: { name: "BINARY_FLOAT" },
    decimal: { name: "DECIMAL" },
    datetime: { name: "TIMESTAMP" },
    timestamp: { name: "TIMESTAMP" },
    timestamptz: { name: "TIMESTAMP WITH TIME ZONE" },
    timestampltz: { name: "TIMESTAMP WITH LOCAL TIME ZONE" },
    time: { name: "TIMESTAMP" },
    date: { name: "DATE" },
    binary: { name: "BLOB" },
    boolean: { name: "NUMBER", limit: 1 },
    raw: { name: "RAW", limit: 2000 },
    bigint: { name: "NUMBER", limit: 19 }
}

https://github.com/rsim/oracle-enhanced/blob/master/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb


1

Kabul edilen cevap harika, düzgün bir şekilde dize vs metin arasındaki farkı açıklar (çoğunlukla veritabanındaki sınır boyutu, ancak birkaç başka gotchas var), ancak bu cevap olarak beni ele geçiren küçük bir sorunu belirtmek istedim tamamen benim için yapmadı.

Maksimum boyut : limit => 1 ila 4294967296 tam olarak belirtildiği gibi çalışmadı, bu maksimum boyuttan -1'e gitmem gerekiyordu. Büyük JSON lekelerini saklıyorum ve bazen çılgınca büyük olabilirler.

İşte MySQL'in şikayet etmediği değerle daha büyük bir değerle geçişim.

Not 5 limit sonunda yerine 6

class ChangeUserSyncRecordDetailsToText < ActiveRecord::Migration[5.1]
  def up
    change_column :user_sync_records, :details, :text, :limit => 4294967295
  end

  def down
    change_column :user_sync_records, :details, :string, :limit => 1000
  end
end

0

Öznitelik f.text_fieldformda eşleşiyorsa string kullanın , eşleşiyorsa metinf.text_area kullanın .

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.