Sự khác biệt giữa chuỗi và văn bản trong đường ray?


435

Tôi đang tạo một ứng dụng web mới bằng Rails và tự hỏi, sự khác biệt giữa stringtext? Và khi nào nên sử dụng mỗi?

Câu trả lời:


522

Sự khác biệt phụ thuộc vào cách biểu tượng được chuyển đổi thành loại cột tương ứng trong ngôn ngữ truy vấn.

với MySQL: chuỗi được ánh xạ tới VARCHAR (255) - http://guides.rubyonrails.org/migations.html

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

Tài liệu tham khảo:

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

Khi nào nên sử dụng mỗi?

Theo nguyên tắc chung, sử dụng :stringcho nhập văn bản ngắn (tên người dùng, email, mật khẩu, tiêu đề, v.v.) và sử dụng :textcho đầu vào dự kiến ​​dài hơn như mô tả, nội dung nhận xét, v.v.


11
Tôi nghĩ rằng một quy tắc tốt hơn là luôn luôn sử dụng :text. Xem depesz.com/2010/03/02/charx-vs-varcharx-vs-varchar-vs-text
Sậy G. Luật

74
Đối với MySQL - không quá nhiều, bạn có thể có các chỉ mục trên varchars, bạn không thể trên văn bản.
Omar Qureshi

12
Thực hiện PostgreSQL thích văn bản. Sự khác biệt duy nhất cho chuỗi pg / văn bản là ràng buộc về độ dài cho chuỗi. Không có sự khác biệt hiệu suất.
Andy Bettisworth

Đây dường như không phải là toàn bộ câu chuyện với ActiveRecord. Lưu giá trị truevào một varchar (ergo, stringloại trường) trong MySQL tuần tự hóa giá trị thành 1(điều này hoàn toàn công bằng). Tuy nhiên, dưới textloại, lưu trữ giá trị "true" kết thúc tuần tự hóa nó dưới dạng char số ít t. Tôi đã di chuyển một cột mà không nhận ra điều này và tất cả các hàng trong tương lai nơi giá trị là đúng t. Có ai có bất kỳ hiểu biết về hành vi này?
Peter

1
@ elli0t có nghĩa là bạn sẽ không thể lập chỉ mục. Nếu điều này quan trọng, thì bạn không nên sử dụng văn bản trên MySQL
Omar Qureshi

157

Nếu bạn đang sử dụng postgres, hãy sử dụng văn bản bất cứ nơi nào bạn có thể, trừ khi bạn có một ràng buộc về kích thước vì không có hình phạt về hiệu suất đối với văn bản so với varchar

Không có sự khác biệt về hiệu năng giữa ba loại này, ngoài không gian lưu trữ tăng lên khi sử dụng loại đệm trống và một vài chu kỳ CPU bổ sung để kiểm tra độ dài khi lưu trữ vào cột bị giới hạn độ dài. Mặc dù ký tự (n) có lợi thế về hiệu năng trong một số hệ thống cơ sở dữ liệu khác, nhưng PostgreQuery không có lợi thế như vậy; trong thực tế, ký tự (n) thường là chậm nhất trong ba vì chi phí lưu trữ bổ sung của nó. Trong hầu hết các tình huống, văn bản hoặc ký tự thay đổi nên được sử dụng thay thế

Hướng dẫn sử dụng PostgreSQL


4
Nhưng vì lợi ích của việc bất khả tri về cơ sở dữ liệu, đây có phải là cách tiếp cận tốt nhất? Nếu bạn muốn thay đổi cơ sở dữ liệu thì sao? Tôi cho rằng, trong thế giới thực không xảy ra thường xuyên, nhưng vẫn ... nếu không có "sự khác biệt về số liệu", tại sao không sử dụng chuỗi dự kiến ​​cho những thứ ngắn và văn bản cho những thứ dài hơn? Và đưa ra chuỗi lập chỉ mục nhận xét của riêng bạn, vẫn có vẻ là cách tiếp cận tốt nhất.
Dan Barron

6
Có bất kỳ lý do nào khiến nó trở nên cần thiết trong Thế giới thực, nơi tốt nhất là đưa ra quan niệm rằng có một Giải pháp đích thực cho mọi vấn đề.
Dan Barron

14
Đó có thể là như vậy, nhưng thuyết bất khả tri của cơ sở dữ liệu là một nhà tiên tri giả.
Omar Qureshi

2
Có ai có bất kỳ thông tin nào về việc liệu hình phạt hiệu suất là đáng kể hay đây là một trường hợp tối ưu hóa sớm? Tôi đoán là bạn sẽ không bao giờ nhận thấy một sự khác biệt, mà phần mở đầu của đoạn dường như xác nhận: "Không có sự khác biệt về hiệu suất giữa ba loại này".
Dennis

5
Bạn đưa ra một quan điểm tốt, nhưng tôi không hoàn toàn bị thuyết phục. Các đối số trong bài đăng trên blog để sử dụng texttrên (n)các loại dữ liệu rất thuyết phục, nhưng đối số cho việc sử dụng texthơn varcharthì không. Anh ta nói họ giống nhau nhưng thích textbởi vì varcharcó thể bị nhầm lẫn varchar(n)và vì textít ký tự hơn để gõ. Nhưng sử dụng textthay vì varchar, bạn sẽ mất bối cảnh dữ liệu được lưu trữ không nên dài. Ví dụ: lưu trữ tên người dùng có textvẻ gây hiểu lầm cho tôi.
Dennis

17

Chuỗi dịch thành "Varchar" trong cơ sở dữ liệu của bạn, trong khi văn bản dịch thành "văn bản". Một varchar có thể chứa các mục ít hơn rất nhiều, một văn bản có thể có (gần như) bất kỳ độ dài nào.

Để có phân tích chuyên sâu với các tài liệu tham khảo tốt, hãy kiểm tra http://www.pythian.com/news/7129/text-vs-varchar/

Chỉnh sửa: Một số công cụ cơ sở dữ liệu có thể tải varchartrong một lần, nhưng lưu trữ văn bản (và blob) bên ngoài bảng. Một SELECT name, amount FROM productsthể, chậm hơn rất nhiều khi sử dụng textcho namehơn khi bạn sử dụng varchar. Và vì Rails, theo mặc định tải các bản ghi với SELECT * FROM...các cột văn bản của bạn sẽ được tải. Điều này có lẽ sẽ không bao giờ là một vấn đề thực sự trong ứng dụng của bạn hoặc của tôi (Tối ưu hóa sớm là ...). Nhưng biết rằng văn bản không phải lúc nào cũng "miễn phí" là điều tốt để biết.


12

Chuỗi nếu kích thước là cố định và nhỏ và văn bản nếu nó là biến và lớn. Đây là loại quan trọng vì văn bản lớn hơn chuỗi. Nó chứa nhiều kilobyte hơn.

Vì vậy, đối với các trường nhỏ luôn luôn sử dụng chuỗi (varchar). Lĩnh vực như thế nào. First_name, đăng nhập, email, chủ đề (của một bài viết hoặc bài đăng) và ví dụ về các văn bản: nội dung / nội dung của một bài viết hoặc bài viết. các trường cho đoạn văn v.v.

Chuỗi kích thước 1 đến 255 (mặc định = 255)

Kích thước văn bản 1 đến 4294967296 (mặc định = 65536) 2


11

Như đã giải thích ở trên, không chỉ kiểu dữ liệu db, nó cũng sẽ ảnh hưởng đến chế độ xem sẽ được tạo nếu bạn đang giàn giáo. chuỗi sẽ tạo một văn bản text_field sẽ tạo ra một text_area


2

Sử dụng chuỗi cho trường ngắn hơn, như tên, địa chỉ, điện thoại, công ty

Sử dụng Văn bản cho nội dung lớn hơn, bình luận, nội dung, đoạn văn.

Quy tắc chung của tôi, nếu đó là một cái gì đó nhiều hơn một dòng, tôi thường đi tìm văn bản, nếu đó là 2-6 từ ngắn, tôi đi theo chuỗi.

Quy tắc chính thức là 255 cho một chuỗi. Vì vậy, nếu chuỗi của bạn có nhiều hơn 255 ký tự, hãy tìm văn bản.


1

Nếu bạn đang sử dụng oracle ... STRINGsẽ được tạo dưới dạng VARCHAR(255)cột và TEXT, như một 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-enhified/blob/master/lib/active_record/connection_ad chương / oracle_enhified_ad CHƯƠNG.rb


1

Câu trả lời được chấp nhận là tuyệt vời, nó giải thích chính xác sự khác biệt giữa chuỗi so với văn bản (chủ yếu là kích thước giới hạn trong cơ sở dữ liệu, nhưng có một vài vấn đề khác), nhưng tôi muốn chỉ ra một vấn đề nhỏ giúp tôi vượt qua nó như câu trả lời đó đã không hoàn toàn làm điều đó cho tôi.

Kích thước tối đa : giới hạn => 1 đến 4294967296 không hoạt động chính xác như đặt, tôi cần đi -1 từ kích thước tối đa đó. Tôi đang lưu trữ các đốm JSON lớn và đôi khi chúng có thể rất lớn.

Đây là sự di chuyển của tôi với giá trị lớn hơn thay cho giá trị mà MySQL không phàn nàn.

Lưu ý 5 ở cuối giới hạn thay vì 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

Nếu thuộc tính phù hợp f.text_fieldtrong biểu mẫu sử dụng chuỗi , nếu nó phù hợp f.text_areasử dụng văn bản .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.