rails mysql2中文編碼及innodb前綴索引長度問題

轉自http://mensfeld.pl/2016/06/ruby-on-rails-mysql2error-incorrect-string-value-and-specified-key-was-too-long/。mysql

Ruby on Rails,Mysql2 ::錯誤:字符串值不正確:'\ xF0 \ x9F \ x99 \ x82',指定的鍵太長; 最大密鑰長度爲767字節

02-06-2016 MACIEJ MENSFELD 0評論sql

若是你收到這樣的錯誤:數據庫

1ruby

Mysql2::Error: Incorrect string value: '\xF0\x9F\x99\x82'ruby-on-rails

這意味着您使用不支持完整Unicode的設置的Mysql版本。在Ruby on Rails中改變它應該是至關簡單的:編碼

1spa

2code

3orm

4排序

5

6

7

8

9

10

11

12

13

14

class ChangeEncoding < ActiveRecord::Migration[5.0]

  def change

    config = Rails.configuration.database_configuration

    db_name = config[Rails.env]["database"]

    collate = 'utf8mb4_polish_ci'

    char_set = 'utf8mb4'

 

    execute("ALTER DATABASE #{db_name} CHARACTER SET #{char_set} COLLATE #{collate};")

 

    ActiveRecord::Base.connection.tables.each do |table|

      execute("ALTER TABLE #{table} CONVERT TO CHARACTER SET #{char_set} COLLATE #{collate};")

    end

  end

end

可是您可能會遇到如下錯誤:

1

Specified key was too long; max key length is 767 bytes

767字節是InnoDB表的前綴限制。

要解決您須要:

  • 更新你的database.yml文件
  • 升級到MySQL 5.7或編輯您的my.cnf   以啓用innodb_large_prefix
  • 將行格式更改成DYNAMIC
  • 使用Ruby on Rails遷移更改數據庫和全部表

Database.yml

您須要更改ActiveRecord的編碼和排序規則:(其中utf8mb4_polish_ci或可爲utf8mb4_unicode_ci)

1

2

3

production:

  encoding: utf8mb4

  collation: utf8mb4_polish_ci

MySQL my.cnf

編輯my.cnf並添加如下行:

1

2

3

innodb_large_prefix=on

innodb_file_format=barracuda

innodb_file_per_table=true

DYNAMIC行格式 (或可忽略)

若是你不這樣作,你可能會(若是你有足夠的索引)會出現這個錯誤:

1

767 bytes is the stated prefix limitation for InnoDB tables

要更改行格式,您須要爲每一個表運行如下查詢:

1

ALTER TABLE table_name ROW_FORMAT=DYNAMIC;

可是,您不須要手動執行此操做 - 下面將會找到一個Ruby on Rails遷移,它將完成全部必要的操做。

複雜的遷移設置一切,就像在MySQL數據庫中同樣

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

class ChangeEncoding < ActiveRecord::Migration[5.0]

  def change

    config = Rails.configuration.database_configuration

    db_name = config[Rails.env]["database"]

    collate = 'utf8mb4_polish_ci'

    char_set = 'utf8mb4'

    row_format = 'DYNAMIC'

 

    execute("ALTER DATABASE #{db_name} CHARACTER SET #{char_set} COLLATE #{collate};")

 

    ActiveRecord::Base.connection.tables.each do |table|

      execute("ALTER TABLE #{table} ROW_FORMAT=#{row_format};")

      execute("ALTER TABLE #{table} CONVERT TO CHARACTER SET #{char_set} COLLATE #{collate};")

    end

  end

end

運行此遷移後,一切都應該正常運行。

 

另補充:

1.該遷移文件則可根據其中聲明的遷移類名來定義,即如20170417033252_change_encoding.rb。

2.數據庫中默認或有ar_internal_metadata和schema_migrations之類的表存在,使得運行上面的遷移的時候發生錯誤而中斷執行,可修改該遷移文件加一if判斷,如

相關文章
相關標籤/搜索