新手问题 SQLite3 数据库怎么保存数组类型?

msl12 · April 09, 2016 · Last by msl12 replied at April 11, 2016 · 9669 hits
class AddLikesCountAndLikedUserIdsToReplies < ActiveRecord::Migration
  def change
    add_column(:replies, :likes_count, :integer, default: 0)
    add_column(:replies, :liked_user_ids, :integer, default: [], array: true)
  end
end

我想通过上面这段代码将 liked_user_ids 字段保存为数组 Array 类型,结果

create_table "replies", force: :cascade do |t|
   t.integer  "user_id",                    null: false
   t.integer  "plan_id",                    null: false
   t.text     "body",                       null: false
   t.datetime "created_at",                 null: false
   t.datetime "updated_at",                 null: false
   t.integer  "likes_count",    default: 0
   t.integer  "liked_user_ids" # 这里并没有反应
 end

怎么解决呢?

网上查了下, https://github.com/rails/rails/issues/10432 这里似乎也有同样问题的人

不支持,只有 NULL, INTEGER, REAL, TEXT, BLOB 五种 https://www.sqlite.org/datatype3.html

Sqlite 和 MySQL 数据库本身都不支持,需要在 model 里面 serialize: http://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html#method-i-serialize 本质上是 text 字段,存取的时候做 json 的转化。

你看的那个问题是 PostgreSQL 的,PostgreSQL 靠插件可以支持 json, array 等类型,而且速度快。

#3 楼 @billy 只能用 serialize 这个来实现存放数组的功能么

ruby-china 源码里有:

create_table "topics", force: :cascade do |t|
    t.integer  "user_id",                               null: false
    t.integer  "node_id",                               null: false
    t.string   "title",                                 null: false
    t.text     "body",                                  null: false
    t.text     "body_html"
    t.integer  "last_reply_id"
    t.integer  "last_reply_user_id"
    t.string   "last_reply_user_login"
    t.string   "node_name"
    t.string   "who_deleted"
    t.integer  "last_active_mark"
    t.boolean  "lock_node",             default: false
    t.datetime "suggested_at"
    t.integer  "excellent",             default: 0
    t.datetime "replied_at"
    t.integer  "replies_count",         default: 0,     null: false
    t.integer  "likes_count",           default: 0
    t.integer  "follower_ids",          default: [],                 array: true
    t.integer  "liked_user_ids",        default: [],                 array: true # 这里可以将其保存为数组?
    t.integer  "mentioned_user_ids",    default: [],                 array: true
    t.datetime "deleted_at"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

#5 楼 @msl12 rubyChina 用的是 PostgreSQL,可以存数组。你也可以选择用 PostgreSQL。

SQLite3 数据库不支持 Array 数组类型,你可以利用自定义 Type 的方式来实现。

谢谢各位,我已经转使用 postgreSQL 数据库了!

You need to Sign in before reply, if you don't have an account, please Sign up first.