Mysqlデータベースに絵文字を格納する方法

#絵文字
絵文字とは語（音形）ではなく、ものや事柄を、絵を文字のように用いて象徴的に示唆したもののことです。

#Mysqlデータベースに絵文字を格納したい場合はどうすれば良いか
皆さんが存じると思いますが、mysqlのデフォルトの文字コードはUTF-8ですが、
UTF-8のデータベースに絵文字を格納できないです。
絵文字を格納したい場合はmysqlのデータベースの文字コードをutf8mb4に変更する必要です。

# Utf8mb4の設定
utf8mb4をサーポートするバージョンは5.5.3+です。
mysqlのmy.confファイルに以下の設定を追加します。

```
   # my.conf
   [client] 
   default-character-set = utf8mb4
   [mysqld]
   character-set-server = utf8mb4
   collation-server = utf8mb4_unicode_ci
   skip-character-set-client-handshake
```

mysqlサーバーを再起動して、文字コードをちゃんと反映されたかどうか、確認します。

```
   mysql> use sample
   Database changed
   mysql> show variables like "char%" ;
   +--------------------------+----------------------------+
   | Variable_name            | Value                      |
   +--------------------------+----------------------------+
   | character_set_client     | utf8mb4                    |
   | character_set_connection | utf8mb4                    |
   | character_set_database   | utf8mb4                    |
   | character_set_filesystem | binary                     |
   | character_set_results    | utf8mb4                    |
   | character_set_server     | utf8mb4                    |
   | character_set_system     | utf8                       |
   | character_sets_dir       | /usr/share/mysql/charsets/ |
   +--------------------------+----------------------------+
   8 rows in set (0.00 sec)
```
上記のようにcharacter_set_client、character_set_connection、character_set_database、character_set_results、character_set_serverがutf8mb4になったらOKです。

#Railsアプリで修正する必要
Railsアプリではデファオルでutf-8文字コードを使うので、utf8mb4を使用するため修正する必要があります。
まず、データベース設定ファイルを修正する。以下のように修正したら、問題なく動くはずです。

```
   development:
      adapter: mysql2
      charset: utf8mb4
      encoding: utf8mb4
      collation: utf8mb4_unicode_ci
      reconnect: false
```

Rails 4+場合上記の設定で動けるが、Rails 3以下を使えば、767バイトに制限されるバグがあります。mysqlはデファオルでインデックスキーのバイト数を767バイトに制限します。Utf8場合は1つ文字が3バイトなので、インデックスキーの文字数が最大255文字です。ですが、Utf8mb4では1つ文字が⒋バイトなので、インデックスキーの文字数が最大191文字しかないです。その原因で、Railsアプリでインデックスを貼る時、エラーが出てしまいます。

修正方法はSchemaStatementsとSchemaMigrationをオーバーライドします。

```rb
// SchemaStatement

   module ActiveRecord
      module ConnectionAdapters # :nodoc:
         module SchemaStatements
            MAX_INDEX_LENGTH_FOR_UTF8MB4 = 191
            def initialize_schema_migrations_table
               if @config[:encoding] == 'utf8mb4'   
                  ActiveRecord::SchemaMigration.create_table(MAX_INDEX_LENGTH_FOR_UTF8MB4)
               else
                  ActiveRecord::SchemaMigration.create_table
               end
            end
         end
      end
   end
```

```rb
// SchemaMigration

   module ActiveRecord            
      class SchemaMigration < ActiveRecord::Base
         def self.index_name
            "#{Base.table_name_prefix}unique_schema_migrations#{Base.table_name_suffix}"
         end

         def self.create_table(limit=nil)
            unless connection.table_exists?(table_name)
               version_options = {null: false}
               version_options[:limit] = limit if limit

               connection.create_table(table_name, id: false) do |t|
                  t.column :version, :string, version_options
               end
               connection.add_index table_name, :version, unique: true, name: index_name
            end
         end               
      end
   end
```

そして、インデックスを貼るmigrationファイルに文字列の文字数を修正します。

```
 add_index :users, :email, unique: true, length: 191
```