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


435

我正在使用Rails的一个新的Web应用程序,并想知道,有什么之间的区别stringtext?以及何时应使用它们?

Answers:


522

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

与MySQL:string映射到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)

参考:

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

什么时候应该使用?

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


11
我认为最好的经验法则是始终使用:text。参见depesz.com/2010/03/02/charx-vs-varcharx-vs-varchar-vs-text
Reed G. Law

74
对于MySQL-并不是很多,您可以在varchars上建立索引,而不能在文本上建立索引。
奥马尔·库雷希

12
PostgreSQL实现更喜欢文本。pg字符串/文本的唯一区别是字符串长度的限制。无性能差异。
Andy Bettisworth 2014年

这似乎不是ActiveRecord的全部内容。将值保存truestringMySQL中的varchar(ergo,类型字段)会将值序列化为1(完全公平)。但是,在texttype 下,存储值“ true”最终将其序列化为单数char t。我迁移了一个列,但没有意识到这一点,并且以后所有值为true的行现在都是t。有人对此行为有见解吗?
彼得

1
@ elli0t表示您将无法编制索引。如果这很重要,那么您不应该在MySQL上使用文本
Omar Qureshi

157

如果您使用的是Postgres,请尽可能使用文本,除非您有大小限制,因为文本与varchar不会降低性能

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

PostsgreSQL手册


4
但是,为了与数据库无关,这是最好的方法吗?如果要更改数据库怎么办?我同意,在现实世界中这种情况不会经常发生,但是...如果没有“性能差异”,为什么不坚持对短字符串使用字符串而对长字符串使用文本呢?考虑到您自己的注释索引字符串,它似乎仍然是最好的方法。
丹·巴伦

6
有多种原因使它在现实世界中变得有必要,在这种情况下,最好摆脱一种观念,即对任何问题都有一个真正的解决方案。
丹·巴伦

14
可能是这样,但是数据库不可知论是一个错误的先知。
奥马尔·库雷希

2
是否有人知道性能损失是否重大或是否为过早优化的信息?我的猜测是您永远不会注意到差异,该段的开头似乎可以确认:“这三种类型之间没有性能差异”。
丹尼斯

5
您的观点很好,但我并不完全相信。该博客文章中有关使用textover (n)数据类型的参数令人信服,但使用textover 的参数varchar则不那么令人信服。他说他们是一样的,但是更喜欢,text因为varchar可以和混淆,varchar(n)因为text键入的字符较少。但是使用text代替varchar,则会丢失上下文,即所存储的数据不应太长。例如,使用来存储用户名text似乎对我产生了误导。
丹尼斯

17

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

有关具有良好参考文献的深入分析,请访问http://www.pythian.com/news/7129/text-vs-varchar/

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


12

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

因此,对于小字段,请始终使用string(varchar)。字段喜欢。名字,登录名,电子邮件,(文章或帖子的)主题和文本示例:文章或文章的内容/正文。段落等字段

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

文字大小1至4294967296(预设= 65536)2


11

如上所述,不仅是db数据类型,它还将影响在脚手架中将生成的视图。字符串将生成一个text_field文本将生成一个text_area


2

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

将文本用于较大的内容,注释,内容,段落。

我的一般规则是,如果内容多于一行,我通常会输入文本;如果是2-6个简短的单词,我会输入字符串。

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


1

如果您使用的是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


1

公认的答案很棒,它可以正确解释字符串与文本之间的区别(主要是数据库的限制大小,但是还有其他一些陷阱),但是我想指出一个小问题,使我得以通过并没有完全为我做

最大大小: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

0

如果属性f.text_field在形式上匹配,请使用字符串;如果属性在形式上匹配,请f.text_area使用文本

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.