Różnica między ciągiem a tekstem w szynach?


435

Tworzę nową aplikację internetową przy użyciu Railsów i zastanawiałem się, jaka jest różnica między stringi text? A kiedy należy z nich korzystać?

Odpowiedzi:


522

Różnica polega na tym, jak symbol jest konwertowany na odpowiedni typ kolumny w języku zapytań.

z MySQL: łańcuch jest mapowany na VARCHAR (255) - 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)

Odniesienie:

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

Kiedy należy stosować każdy z nich?

Zasadniczo należy używać :stringdo wprowadzania krótkich tekstów (nazwa użytkownika, adres e-mail, hasło, tytuły itp.) I używać :textdo dłuższych oczekiwanych danych wejściowych, takich jak opisy, treść komentarzy itp.


11
Myślę, że lepszą zasadą jest zawsze używać :text. Patrz depesz.com/2010/03/02/charx-vs-varcharx-vs-varchar-vs-text
Reed G. Law

74
W przypadku MySQL - nie tyle, możesz mieć indeksy na varcharach, nie możesz na tekście.
Omar Qureshi

12
Implementacja PostgreSQL preferuje tekst. Jedyną różnicą dla łańcucha / tekstu pg jest ograniczenie długości łańcucha. Brak różnic w wydajności.
Andy Bettisworth,

To nie wydaje się być cała historia z ActiveRecord. Zapisanie wartości truew varchar (pole ergo, stringtype) w MySQL serializuje wartość do 1(co jest całkowicie uczciwe). Jednak w texttypie zapisanie wartości „true” kończy się szeregowaniem jej jako pojedynczego znaku t. Migrowałem kolumnę, nie zdając sobie z tego sprawy, i wszystkie przyszłe wiersze, w których wartość jest prawdziwa, są teraz t. Czy ktoś ma wgląd w to zachowanie?
Peter,

1
@ elli0t oznacza, że ​​nie będziesz mógł indeksować. Jeśli jest to ważne, nie powinieneś używać tekstu na MySQL
Omar Qureshi

157

Jeśli korzystasz z Postgres, używaj tekstu gdziekolwiek możesz, chyba że masz ograniczenie rozmiaru, ponieważ nie ma ograniczenia wydajności dla tekstu w porównaniu z varchar

Nie ma żadnej różnicy w wydajności między tymi trzema typami, oprócz zwiększonej przestrzeni dyskowej przy użyciu pustego wypełnienia i kilku dodatkowych cykli procesora, aby sprawdzić długość podczas przechowywania w kolumnie o ograniczonej długości. Chociaż znak (n) ma przewagę wydajności w niektórych innych systemach baz danych, nie ma takiej przewagi w PostgreSQL; w rzeczywistości znak (n) jest zwykle najwolniejszy z trzech ze względu na dodatkowe koszty przechowywania. W większości sytuacji zamiast tego należy używać tekstu lub różnych znaków

Podręcznik PostsgreSQL


4
Ale czy w interesie bycia niezależnym od bazy danych jest to najlepsze podejście? Co jeśli chcesz zmienić bazę danych? Przyznaję, w prawdziwym świecie, który nie zdarza się tak często, ale nadal ... jeśli nie ma „różnicy w wynikach”, dlaczego nie trzymać się oczekiwanego użycia łańcucha dla krótkich rzeczy i tekstu dla dłuższych rzeczy? Biorąc pod uwagę własne ciągi indeksujące komentarze, nadal wydaje się najlepszym podejściem.
Dan Barron

6
Istnieje wiele powodów, dla których może to okazać się konieczne w świecie rzeczywistym, w którym najlepiej jest porzucić pogląd, że istnieje jedno prawdziwe rozwiązanie każdego problemu.
Dan Barron

14
Tak może być, ale agnostycyzm bazy danych jest fałszywym prorokiem.
Omar Qureshi

2
Czy ktoś ma jakieś informacje na temat tego, czy spadek wydajności jest znaczący, czy jest to przypadek przedwczesnej optymalizacji? Domyślam się, że nigdy nie zauważysz różnicy, co wydaje się potwierdzać otwarcie akapitu: „Nie ma różnicy w wydajności między tymi trzema typami”.
Dennis

5
Masz rację, ale nie jestem do końca przekonany. Argumenty w tym blogu korzystania textprzez (n)typy danych są przekonujące, ale argument za korzystanie textprzez varcharnie. Mówi, że są takie same, ale woli, textponieważ varcharmożna go pomylić varchar(n)i ponieważ textjest mniej znaków do pisania. Ale textzamiast tego varchartracisz kontekst, że przechowywane dane nie powinny być długie. Na przykład przechowywanie nazwy użytkownika textwydaje mi się mylące.
Dennis

17

Łańcuch przekłada się na „Varchar” w bazie danych, podczas gdy tekst tłumaczy się na „tekst”. Varchar może zawierać znacznie mniej elementów, tekst może mieć (prawie) dowolną długość.

Aby uzyskać dogłębną analizę z dobrymi referencjami, sprawdź http://www.pythian.com/news/7129/text-vs-varchar/

Edycja: Niektóre silniki baz danych mogą być ładowane varcharza jednym razem, ale przechowują tekst (i obiekt blob) poza tabelą. SELECT name, amount FROM productsMogłaby być o wiele wolniej podczas korzystania textz nameniż podczas używania varchar. A ponieważ Railsy domyślnie SELECT * FROM...ładują rekordy z kolumnami tekstowymi, zostaną załadowane. Prawdopodobnie nigdy nie będzie to prawdziwym problemem w Twojej lub mojej aplikacji (przedwczesna optymalizacja to ...). Ale dobrze wiedzieć, że tekst nie zawsze jest „darmowy”.


12

Ciąg, jeśli rozmiar jest stały i mały, a tekst, jeśli jest zmienny i duży. Jest to trochę ważne, ponieważ tekst jest znacznie większy niż napisy. Zawiera znacznie więcej kilobajtów.

Dlatego w przypadku małych pól zawsze używaj łańcucha (varchar). Pola takie jak. imię, login, adres e-mail, temat (artykułu lub postu) i przykład tekstów: treść / treść postu lub artykułu. pola na akapity itp

Rozmiar łańcucha od 1 do 255 (domyślnie = 255)

Rozmiar tekstu od 1 do 4294967296 (domyślnie = 65536) 2


11

Jak wyjaśniono powyżej, nie tylko typ danych db wpłynie również na widok, który zostanie wygenerowany podczas rusztowania. łańcuch wygeneruje pole tekstowe tekst wygeneruje obszar tekstowy


2

Użyj ciągu dla krótszych pól, takich jak nazwiska, adres, telefon, firma

Użyj Tekstu dla większych treści, komentarzy, treści, akapitów.

Zasadą ogólną jest to, że jeśli jest to coś więcej niż jedna linia, zazwyczaj wybieram tekst, jeśli jest to 2-6 słów, wybieram ciąg znaków.

Oficjalna reguła to 255 dla ciągu. Jeśli więc ciąg ma więcej niż 255 znaków, przejdź do tekstu.


1

Jeśli używasz oracle ... STRINGzostanie utworzony jako VARCHAR(255)kolumna i TEXTjako 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

Przyjęta odpowiedź jest niesamowita, właściwie wyjaśnia różnicę między ciągiem a tekstem (głównie w limicie rozmiaru bazy danych, ale istnieje kilka innych błędów), ale chciałem wskazać na mały problem, który pomógł mi przejść przez tę odpowiedź nie zrobiłem tego całkowicie dla mnie.

Maksymalny rozmiar : limit => 1 do 4294967296 nie działał dokładnie tak, jak podano, musiałem przejść -1 z tego maksymalnego rozmiaru. Przechowuję duże obiekty BLS JSON i czasami mogą być szalone ogromne.

Oto moja migracja z większą wartością i wartością, na którą MySQL nie narzeka.

Uwaga 5 na końcu limitu zamiast 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

Jeśli atrybut jest zgodny f.text_fieldz formularzem, użyj ciągu znaków , jeśli jest zgodny, f.text_areaużyj tekstu .

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.