【问题标题】:Difference between string and text in rails?rails中的字符串和文本之间的区别?
【发布时间】:2011-03-22 05:24:51
【问题描述】:

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

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

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

    用 MySQL :string 映射到 VARCHAR(255)

    :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 上建立索引,你不能在 text 上。
    • PostgreSQL 实现更喜欢文本。 pg 字符串/文本的唯一区别是对字符串长度的限制。没有性能差异。
    • 这似乎不是 ActiveRecord 的全部内容。将值 true 保存到 MySQL 中的 varchar(ergo,string 类型字段)会将值序列化为 1(这是完全公平的)。但是,在text 类型下,存储值“true”最终会将其序列化为单个字符t。我在没有意识到这一点的情况下迁移了一个列,并且该值为 true 的所有未来行现在都是 t。有没有人对此行为有任何见解?
    • @elli0t 这意味着您将无法建立索引。如果这很重要,那么您不应该在 MySQL 上使用文本
    【解决方案2】:

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

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

    PostsgreSQL manual

    【讨论】:

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

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

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

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

    【讨论】:

      【解决方案4】:

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

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

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

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

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          【解决方案6】:

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

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

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

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

          【讨论】:

            【解决方案7】:

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

            最大尺寸 :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 版本)。
            【解决方案8】:

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

            【讨论】:

              【解决方案9】:

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

              【讨论】:

                猜你喜欢
                • 2016-07-14
                • 2017-01-29
                • 2013-05-26
                • 2011-03-18
                • 1970-01-01
                • 2016-08-16
                • 1970-01-01
                • 1970-01-01
                • 2016-10-22
                相关资源
                最近更新 更多