ChatGPT解决这个技术问题 Extra ChatGPT

rails中的字符串和文本之间的区别?

我正在使用 Rails 制作一个新的网络应用程序,并且想知道 stringtext 之间有什么区别?什么时候应该使用它们?


D
Dave Powers

区别在于符号如何转换为查询语言中的相应列类型。

使用 MySQL :string 映射到 VARCHAR(255) https://edgeguides.rubyonrails.org/active_record_migrations.html

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

参考:

https://hub.packtpub.com/working-rails-activerecord-migrations-models-scaffolding-and-database-completion/

什么时候应该使用每个?

作为一般经验法则,将 :string 用于短文本输入(用户名、电子邮件、密码、标题等),将 :text 用于预期较长的输入,例如描述、评论内容等。


我认为更好的经验法则是始终使用 :text。请参阅depesz.com/2010/03/02/charx-vs-varcharx-vs-varchar-vs-text
对于 MySQL - 不是那么多,你可以在 varchars 上有索引,你不能在文本上。
PostgreSQL 实现更喜欢文本。 pg 字符串/文本的唯一区别是对字符串长度的限制。没有性能差异。
这似乎不是 ActiveRecord 的全部内容。将值 true 保存到 MySQL 中的 varchar(ergo,string 类型字段)会将值序列化为 1(这是完全公平的)。但是,在 text 类型下,存储值“true”最终会将其序列化为单数字符 t。我在没有意识到这一点的情况下迁移了一个列,并且该值为 true 的所有未来行现在都是 t。有人对这种行为有任何见解吗?
@elli0t 这意味着您将无法索引。如果这很重要,那么您不应该在 MySQL 上使用文本
O
Omar Qureshi

如果您使用 postgres,请尽可能使用 text,除非您有大小限制,因为 text 与 varchar 没有性能损失

这三种类型之间没有性能差异,除了在使用空白填充类型时增加了存储空间,以及在存储到长度受限的列时需要一些额外的 CPU 周期来检查长度。虽然 character(n) 在其他一些数据库系统中具有性能优势,但在 PostgreSQL 中没有这样的优势;事实上 character(n) 通常是三个中最慢的,因为它有额外的存储成本。在大多数情况下,应该使用文本或字符变化来代替

PostsgreSQL manual


但是为了与数据库无关,这是最好的方法吗?如果要更改数据库怎么办?我承认,在现实世界中这种情况并不经常发生,但仍然......如果没有“性能差异”,为什么不坚持预期使用字符串来处理简短的事情,而使用文本来处理更长的事情呢?并且给定您自己的评论索引字符串,似乎仍然是最好的方法。
在现实世界中它可能成为必要的原因有很多,最好摆脱对任何问题都有一个真正的解决方案的观念。
可能是这样,但数据库不可知论是一个假先知。
有没有人知道性能损失是否显着或者这是过早优化的情况?我的猜测是您永远不会注意到差异,该段落的开头似乎证实了这一点:“这三种类型之间没有性能差异”。
你说得很好,但我并不完全相信。该博客文章中关于使用 text 而不是 (n) 数据类型的论点是令人信服的,但使用 text 而不是 varchar 的论点则不是。他说它们是相同的,但更喜欢 text,因为 varchar 可能与 varchar(n) 混淆,而且 text 输入的字符更少。但是使用 text 而不是 varchar,您会失去所存储的数据不应长的上下文。例如,使用 text 存储用户名似乎会误导我。
b
berkes

字符串在您的数据库中转换为“Varchar”,而文本转换为“文本”。 varchar 可以包含更少的项目,文本可以是(几乎)任何长度。

对于具有良好参考的深入分析,请检查 http://www.pythian.com/news/7129/text-vs-varchar/

编辑: 一些数据库引擎可以一次性加载 varchar,但将文本(和 blob)存储在表之外。将 text 用于 name 时,SELECT name, amount FROM products 可能比使用 varchar 时慢很多。而且由于 Rails,默认情况下会加载带有 SELECT * FROM... 的记录,您的文本列将被加载。不过,这在您或我的应用程序中可能永远不会成为真正的问题(过早的优化是......)。但是知道文本并不总是“免费”是件好事。


G
Gurudath BN

如果大小是固定的且小,则为字符串;如果大小为可变且大,则为文本。这一点很重要,因为文本比字符串大得多。它包含更多的千字节。

所以对于小字段总是使用字符串(varchar)。领域之类的。名字、登录名、电子邮件、主题(文章或帖子)和文本示例:帖子或文章的内容/正文。段落等字段

字符串大小 1 到 255(默认 = 255)

文本大小 1 到 4294967296(默认 = 65536)2


R
Ravi D

如上所述,不仅是 db 数据类型,它还会影响在搭建脚手架时将生成的视图。 string 将生成一个 text_field text 将生成一个 text_area


u
user2012677

对较短的字段使用字符串,例如姓名、地址、电话、公司

将文本用于更大的内容、评论、内容、段落。

我的一般规则是,如果它的内容超过一行,我通常会选择文本,如果是 2-6 个单词,我会选择字符串。

一个字符串的官方规则是 255。因此,如果您的字符串超过 255 个字符,请使用文本。


n
nategurutech

接受的答案很棒,它正确解释了字符串与文本之间的区别(主要是数据库中的限制大小,但还有一些其他问题),但我想指出一个让我通过它的小问题作为答案没有完全为我做。

最大尺寸 :limit => 1 到 4294967296 并没有完全按照预期工作,我需要从最大尺寸变为 -1。我正在存储大型 JSON blob,有时它们可能会非常大。

这是我的迁移,其中较大的值具有 MySQL 没有抱怨的值。

注意限制末尾的 5 而不是 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

对于那些使用 postgresql 并希望存储 JSON 数据的人,最好使用本机 jsonb 类型(但请先检查您的 postgresql 版本)。
L
Luis

如果您使用 oracle... STRING 将创建为 VARCHAR(255) 列,TEXT 将创建为 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


v
veben

如果属性匹配表单中的 f.text_field,则使用 string,如果匹配 f.text_area,则使用 text