我正在使用 Rails 制作一个新的网络应用程序,并且想知道 string
和 text
之间有什么区别?什么时候应该使用它们?
区别在于符号如何转换为查询语言中的相应列类型。
使用 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
用于预期较长的输入,例如描述、评论内容等。
如果您使用 postgres,请尽可能使用 text,除非您有大小限制,因为 text 与 varchar 没有性能损失
这三种类型之间没有性能差异,除了在使用空白填充类型时增加了存储空间,以及在存储到长度受限的列时需要一些额外的 CPU 周期来检查长度。虽然 character(n) 在其他一些数据库系统中具有性能优势,但在 PostgreSQL 中没有这样的优势;事实上 character(n) 通常是三个中最慢的,因为它有额外的存储成本。在大多数情况下,应该使用文本或字符变化来代替
text
而不是 (n)
数据类型的论点是令人信服的,但使用 text
而不是 varchar
的论点则不是。他说它们是相同的,但更喜欢 text
,因为 varchar
可能与 varchar(n)
混淆,而且 text
输入的字符更少。但是使用 text
而不是 varchar
,您会失去所存储的数据不应长的上下文。例如,使用 text
存储用户名似乎会误导我。
字符串在您的数据库中转换为“Varchar”,而文本转换为“文本”。 varchar 可以包含更少的项目,文本可以是(几乎)任何长度。
对于具有良好参考的深入分析,请检查 http://www.pythian.com/news/7129/text-vs-varchar/
编辑: 一些数据库引擎可以一次性加载 varchar
,但将文本(和 blob)存储在表之外。将 text
用于 name
时,SELECT name, amount FROM products
可能比使用 varchar
时慢很多。而且由于 Rails,默认情况下会加载带有 SELECT * FROM...
的记录,您的文本列将被加载。不过,这在您或我的应用程序中可能永远不会成为真正的问题(过早的优化是......)。但是知道文本并不总是“免费”是件好事。
如果大小是固定的且小,则为字符串;如果大小为可变且大,则为文本。这一点很重要,因为文本比字符串大得多。它包含更多的千字节。
所以对于小字段总是使用字符串(varchar)。领域之类的。名字、登录名、电子邮件、主题(文章或帖子)和文本示例:帖子或文章的内容/正文。段落等字段
字符串大小 1 到 255(默认 = 255)
文本大小 1 到 4294967296(默认 = 65536)2
如上所述,不仅是 db 数据类型,它还会影响在搭建脚手架时将生成的视图。 string 将生成一个 text_field text 将生成一个 text_area
对较短的字段使用字符串,例如姓名、地址、电话、公司
将文本用于更大的内容、评论、内容、段落。
我的一般规则是,如果它的内容超过一行,我通常会选择文本,如果是 2-6 个单词,我会选择字符串。
一个字符串的官方规则是 255。因此,如果您的字符串超过 255 个字符,请使用文本。
接受的答案很棒,它正确解释了字符串与文本之间的区别(主要是数据库中的限制大小,但还有一些其他问题),但我想指出一个让我通过它的小问题作为答案没有完全为我做。
最大尺寸 :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
如果您使用 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 }
}
如果属性匹配表单中的 f.text_field
,则使用 string,如果匹配 f.text_area
,则使用 text。
不定期副业成功案例分享
:text
。请参阅depesz.com/2010/03/02/charx-vs-varcharx-vs-varchar-vs-texttrue
保存到 MySQL 中的 varchar(ergo,string
类型字段)会将值序列化为1
(这是完全公平的)。但是,在text
类型下,存储值“true”最终会将其序列化为单数字符t
。我在没有意识到这一点的情况下迁移了一个列,并且该值为 true 的所有未来行现在都是t
。有人对这种行为有任何见解吗?