美文网首页react + dva + antd
PostgreSQL 和 Rails 的枚举类型 (六)

PostgreSQL 和 Rails 的枚举类型 (六)

作者: 求知久久编程学院 | 来源:发表于2020-01-16 14:56 被阅读0次

    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
    

    完结。

    相关文章

      网友评论

        本文标题:PostgreSQL 和 Rails 的枚举类型 (六)

        本文链接:https://www.haomeiwen.com/subject/pwvfzctx.html