世界上最伟大的投资就是投资自己的教育
PostgreSQL 和 Rails 的枚举类型 (六)
随风发布于2657 次阅读
1. 传统方式
有很多数据或资源是这样,具有一个类型或状态属性,比如,订单有 pending,approve 状态,博文有草稿 (draft),出版 (published) 的状态,而一般来存这种数据可以选择存成字符串 (string),或整型 (integer)。建议如果是中文的字符串就不要存进数据库了,不存可以避免很多问题。而大多数人是存整形,就是数字 1、2、3 之类,比如,1 代表 draft,2 代表 published,这样可以节约空间啊,整型肯定比字符串占用的空间小些,如果要读出 1 或 2 代表的数据,用一个常量 hash 来匹配就好了,比如STATUS_TEXT = { 1: '待处理', 2: '操盘中', 3: '已完结' }
。
而 Rails 的 activerecord 也支持 enum 方法,来支持更多的判断等操作。比如
class Conversation < ActiveRecord::Base
enum status: [ :active, :archived ]
end
# conversation.update! status: 0
conversation.active!
conversation.active? # => true
conversation.status # => "active"
# 返回所有类型
Conversation.statuses # => { "active" => 0, "archived" => 1 }
2. PostgreSQL 的枚举类型
PostgreSQL 官方文档enum介绍了枚举类型和它的操作。
创建枚举类型。
CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');
使用只要指定 TYPE 的名称即可。
CREATE TABLE person (
name text,
current_mood mood
);
INSERT INTO person VALUES ('Moe', 'happy');
SELECT * FROM person WHERE current_mood = 'happy';
name | current_mood
------+--------------
Moe | happy
(1 row)
functions-enum这里有 enum 所有支持的函数。
2. 在 Rails 中的使用
添加枚举的列。
# 20151009022320_add_status_to_articles.rb
class AddStatusToArticles < ActiveRecord::Migration
def up
execute <<-SQL
CREATE TYPE article_status AS ENUM ('draft', 'published');
SQL
add_column :articles, :status, index: true
end
def down
execute <<-SQL
DROP TYPE article_status;
SQL
remove_column :articles, :status
end
end
在 article.rb 中定义 enum。
# article.rb
class Article < ActiveRecord::Base
enum status: {
draft: 'draft',
published: 'published'
}
end
假如之后有另外的值要添加的话,那也简单。用ALTER TYPE
命令即可。
ALTER TYPE enum_type ADD VALUE 'new_value'; -- appends to list
ALTER TYPE enum_type ADD VALUE 'new_value' BEFORE 'old_value';
ALTER TYPE enum_type ADD VALUE 'new_value' AFTER 'old_value';
用 Rails 可以这样做。
disable_ddl_transaction!
def up
execute <<-SQL
ALTER TYPE article_status ADD VALUE IF NOT EXISTS 'archived' AFTER 'published';
SQL
end
查看数据库的所有枚举类型可以这样。
SELECT n.nspname AS enum_schema,
t.typname AS enum_name,
e.enumlabel AS enum_value
FROM pg_type t
JOIN pg_enum e ON t.oid = e.enumtypid
JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
完结。
本站文章均为原创内容,如需转载请注明出处,谢谢。
0 条回复
暂无回复~~
© 汕尾市求知科技有限公司 | Rails365 Gitlab | 知乎 | b 站 | csdn
粤公网安备 44152102000088号 | 粤ICP备19038915号
Top