ã¯ããã¾ãã¦ããã¼ãã¬ã¤ã«ãºã®å¢ (@kazsakai) ã§ãã
è²ã ãã£ã¦ä»ã¯é·éçã®ä¼é£ã¨ãããå°ççã«ã¯æ¥æ¬åå³¶ã®ä¸å¿ãã¸ãã ãã©ãããã大é½å¸ããæºéãªãé ãçç°èã«æ®ããã¦ãã¾ãã(ã¡ãªã¿ã«ã¢ãã¡èå°å·¡ç¤¼çºç¥¥ã®å°ã ããã§)
Kaizen Platformããã®ç¤¾å¡ã§ã¯ãªããã¼ããã¼ã¨ããç«å ´ã§ã¯ããã¾ãããã»ã¼æåæãããããéçºã«é¢ãã£ã¦ããã¨ã³ã¸ãã¢ã®ä¸äººã¨ãã¦ãä»åãã¡ãã®ããã°ã«ãéªéããã¦ããã ãã¾ãã
Rails ã®ä¸è¦ãã¼ãã«ã¨ migration ãã¡ã¤ã«ãæ´çããã
Kaizen Platformããã®ãããã¯ãã¯æ¥ã çå®ã«æ¡å¤§ãç¶ãã¦ãã¦ãgithubã®ç¤¾å ãªãã¸ããªæ°ãä»ã200ãè¶ ãã¦ãã¾ããããããªKaizenã®ãããã¯ããæåæã«ã¯åä¸ã®Railsãªãã¸ããªããã¹ã¿ã¼ããã¾ããã
æåæã®ãããã¯ãåãplanBCDãã«ã¡ãªãã ãã®Railsãªãã¸ããªplanbcd
ã¯ãå°ããã¤ãªãã¡ã¯ã¿ãªã³ã°ãããªããä»ã§ããµã¼ãã¹ã®ä¸æ ¸ã«æ®ãç¶ãã¦ãã¾ãã
ãããããã®planbcd
ã¯ãããã«ãã5å¹´ãè¶
ããæ³æãçµããªãã¸ããªã ããã£ã¦ããã®éã«å
é¨ã®ãã¼ã¿æ§é ãæ§ã
ãªå¤é·ãçµã¦ãã¦ãMySQLã®ãã¼ãã«å¨ããããªãæ£ããã£ãç¶æ
ã«ãªã£ã¦ãã¾ããã
å ·ä½çã«ã¯ã
- ãã使ã£ã¦ãªãã¯ãã®ãã¼ãã«ã
db/schema.rb
ã«è¼ã£ã¦ãã - æ°ããDBãä½ã£ã¦
rake db:migrate
ããã¨migrationãã¡ã¤ã«ç¾¤ã®è²ããªã¨ããã§ã¨ã©ã¼ãåºã¦åããªã
çã ã®èª²é¡ããã£ã¦ãè´å½çã¨ããããã§ã¯ãªãããã©ãæ¾ã£ã¦ããããããªãç¶æ ã«ããã¾ããã
åã ããä½ã¨ããããã¨ã¯æã£ã¦ããã®ã§ãããæè¿æ°ããæ©è½ããªãªã¼ã¹ãã¦ä¸æ¯ã¤ããã¿ã¤ãã³ã°ã§ãã®åé¡ãè§£æ¶ããæ©ä¼ã«æµã¾ãã¾ããã®ã§ãä»åã¯ã©ããã£ã¦ããããè§£æ¶ããã®ããç´¹ä»ãããã¨æãã¾ãã
ä¸è¦ãªãã¼ãã«ãåé¤ãã
è§£æ¶åã®æç¹ã§planbcd
ã«ã¯MySQLã®ãã¼ãã«ã165åããã¾ãããããã®ãã¡ç¾å¨ã¯ãã使ããã¦ããªããããªãã®ã夿°åå¨ãã¦ãã¾ããã
ããããæ®ã£ã¦ãã¦ãã³ã¼ããDBãçºããéã«ãã¤ãºã«ãããªããªãã®ã§ã使ããã¦ããªããã®ã¯åé¤ãããã¨ã«ãã¾ããã
Rails ã§ä½¿ã£ã¦ããªããã¼ãã«ãæ¢ã
ã¾ãæ¬å½ã«ä½¿ããã¦ããªããã©ããã調ã¹ãããã«ãã¡ãã£ã¨ããã¹ã¯ãªãããèµ°ããã¦ã¿ã¾ãã
Rails
ã§æ®éã«ActiveRecord
ã使ã£ã¦ãã¼ãã«ãä½æã»æä½ããã¨ãã¬ã³ã¼ãã®INSERT
ãUPDATE
ã®ã¨ãã«èªåçã«updated_at
ã«ã©ã ã«ãã®æç¹ã®æ¥ä»ãå
¥ãã¾ãã
(update_column
ãupdate_all
ã¡ã½ããã使ãã¨å
¥ããªãã®ã§ãããKaizenããã§ãããã®ããè¡åã®æªãã¡ã½ããã使ã人ã¯å以å¤ãã¾ãããªãã®ã§ã大ä½ãã®ã«ã©ã ãä¿¡ç¨ã§ãããã§ãã)
ãããå©ç¨ãã¦ãåãã¼ãã«ã®æçµæ´æ°æ¥æã¨ãã¤ãã§ã«ã¬ã³ã¼ãæ°ã調ã¹ã¦ã¿ã¾ãã
railsã³ã³ã½ã¼ã«ä¸ã§ã
ActiveRecord::Base.connection.tables.map do |table_name| count = ActiveRecord::Base.connection.select_value("SELECT COUNT(*) FROM #{table_name}") column_names = ActiveRecord::Base.connection.columns(table_name).map(&:name) time_column = column_names.include?('updated_at') ? :updated_at : nil time_column ||= column_names.include?('created_at') ? :created_at : nil last_updated_at = nil if time_column && count > 0 sql = "SELECT #{time_column} FROM #{table_name} ORDER BY #{time_column} DESC LIMIT 1" last_updated_at = ActiveRecord::Base.connection.select_value(sql) end { table_name: table_name, count: count, time_column: time_column, last_updated_at: last_updated_at, } end
ã®ãããªã¹ã¯ãªãããèµ°ããã¦ã
=> [{:table_name=>"account_statements", :count=>22323, :time_column=>:updated_at, :last_updated_at=>2016-03-02 03:02:34 UTC}, {:table_name=>"acct_areas", :count=>2, :time_column=>:updated_at, :last_updated_at=>2015-05-14 00:40:46 UTC}, {:table_name=>"acct_contact_roles", :count=>146, :time_column=>:updated_at, :last_updated_at=>2015-12-04 23:36:44 UTC}, ...]
ã®ããã«ãã¼ãã«åãã¬ã³ã¼ãæ°ãæçµæ´æ°æ¥æãåå¾ãã¦ã¿ã¾ããã
ããã§å
¨ãã¼ãã«åã®åå¾çã«ActiveRecord::Base.connection
ã使ã£ã¦ãã¾ãããããã«ã¯Railsã®ã³ã³ã½ã¼ã«ãã¹ã¯ãªããã§ç SQL ãå©ããã (execute
ãselect_all
) ãã¼ãã«ã®ã¹ãã¼ããå¤ããã (add_column
ãcreate_index
) ã§ããã¡ã½ãããè©°ã¾ã£ã¦ããã®ã§ãè¦ãã¦ããã¨ã¡ãã£ã¨ããã¨ãã«ä½¿ãã¦ä¾¿å©ã§ãã
ãããã¦åå¾ãããã¼ãã«ä¸è¦§ãçºãã¦ãæ¬å½ã«ä½¿ããã¦ããªããã©ããã®å¤æã®ææã¨ãã¾ãã ä¾ãã°ã¬ã³ã¼ãæ°ã¯å¤§éã«ããã®ã«æçµæ´æ°æ¥æãæ°å¹´åã§æ¢ã¾ã£ã¦ãããã¼ãã«ãªã©ã¯é«ç¢ºçã§ãã使ããã¦ããªãã¨æã£ã¦ããã§ãããã
ãã å®éã«ã¯ããã ãã§å¤æããããã§ã¯ãªããRailsã®ã³ã¼ãã¨ããã¨ãã¼ãã«ã®å½¹å²ãæ´å²ççµç·¯ããè¦ã¦ããã¯ã¾ã è¦ãã¯ããããã¯ããè¦ããªãã¯ãã¨ç·åçã«å¤æãã¦ããã¾ããã
ããããçµæã66åã®æ¶ãã¦ããããããªãã¼ãã«ã®ãªã¹ããã§ããããã¾ããã
ãããªãæ¶ããã«ãªãã¼ã ãã¦æ§åãè¦ã
165åä¸66åã®ãã¼ãã«ãæ¶ãããã§ãããããããªããã®æ°ã®ãã¼ãã«ãæ¶ãã®ã¯æãã®ã§ãåé¤ã®åã«ãã䏿®µéæããã¨ã«ãã¾ãã
ã¾ãããããªé¢¨ã«åé¤äºå®ã®ãã¼ãã«ãå¥ã®ååã«ãªãã¼ã ããmigrationãã¡ã¤ã«ãç¨æãã¾ããã
class RenameLegacyTables < ActiveRecord::Migration def change rename_table :acct_areas, :zzz_acct_areas rename_table :acct_contact_roles, :zzz_acct_contact_roles # ...ç¥... end end
ãããã¼ãã«ãæ¶ãã¦åé¡ãèµ·ãããããªããªãã¼ã ããã ãã§ãåãåé¡ãèµ·ããã¯ããªã®ã§ããããã¦ãªãã¼ã ãã¦æ§åãè¦ããã¨ã«ãã¾ãã
ä»åããªãã¼ã å¾ã®ååã¯åããããããã°ãªãã§ãè¯ãã£ãã®ã§zzz_
ãã¤ãã¦ã¿ã¾ããã
ãã rename_table
ã§ã¯ãã¼ãã«ã¨åæã«ãã®ãã¼ãã«ã«å¼µãããã¤ã³ããã¯ã¹ããªãã¼ã ããã¦ãMySQLã®ååã®ä¸é64åãè¶
ããã¨ã©ã¼ãå¹¾ã¤ãåºã¦ãã¾ã£ãã®ã§ããã®ãããã¯å¥éã¤ã³ããã¯ã¹ã®æ¹ããªãã¼ã ãã¦ãã¾ããã
ããã¯ããã¡ãã£ã¨çããã¬ãã£ãã¯ã¹ããååãé·ããªããªããããªå½åã®æ¹ãè¯ãã£ãããããã¾ããã
ã¨ããããããã¦åé¤äºå®ã®ãã¼ãã«ããªãã¼ã å¾ãèªåãã¹ãã®å ¨ãã¹ã¨ã¹ãã¼ã¸ã³ã°ç°å¢ã§ã®ç¢ºèªãçµã¦ãæ¬çªç°å¢ã¸ã¨åæ ãã¾ãã ãªãã¼ã ããç¶æ ã§æ¬çªç°å¢ã§ãã°ããéç¨ãã¦ãåé¡ãèµ·ãããªããã°ãã¼ãã«åé¤ããäºå®ã§ããã
ãããã¯ãæ³å®å¤ã®åé¡ã®ä¸ã¤ãäºã¤ã¯èµ·ãããã®ã§ãChartioã§æ¸ãã¦ããã°ã©ãã®ä¸ã¤ãåããªããªãã¨ããåé¡ãçºçãã¦ãã¾ãã¾ããã Chartioã®ã¯ã¨ãªã§ä»ååé¤ãããã¨ãã¦ãããã¼ãã«ã®å¹¾ã¤ããåç §ããã¦ãã¦ãããã«æ°ã¥ããªãã¾ã¾ãªãã¼ã ãã¦ãã¾ã£ãã®ã§ãã
幸ããKaizen社å ã§åç §ããææ¨ã®ããã®ã°ã©ãã§ã¦ã¼ã¶ã¼å½±é¿ã¯ç¡ãã£ãã®ã§ããããªãã¼ã ã ãã«ãã¦ããããããã復æ§ãããã¨ãã§ãã¾ããã ãã¼ãã«åé¤ãã¦ããããããã¯ã¢ããããã®å¾©æ§ã¨ãªãããå°ãææ°ãããã£ã¦ããã¨æãã¾ãã
ãããã¦ä¸é¨ã®ãã¼ãã«ã¯å ã«æ»ãããã®ã®ã以éä¸é±éã»ã©æ§åãè¦ã¦ãç¹ã«åé¡ã¯èµ·ããããæ®ãã®ãã¼ãã«ã¯æ¬å½ã«æ¶ãã¦ããããããªã®ã§ãå®éã«åé¤ã¸ã¨é²ã¿ã¾ãã
ãã¼ãã«ãããã¯ã¢ãããåã£ã¦åé¤ãã
æ¬å½ã«æ¶ãã¦ããããããªãã¼ãã«ãåãã£ã¦ããã®ã§ãä»åº¦ã¯ãããããããªmigrationãã¡ã¤ã«ã§åé¤ãã¾ãã
class DropLegacyTables < ActiveRecord::Migration def backup_table(name, timestamp) local_d = "#{Rails.root}/dump" Dir.mkdir(local_d) unless File.directory? local_d dumpfile = "#{local_d}/#{timestamp}-#{Rails.env}-#{name}.dump.gz" options = connection.raw_connection.query_options.slice(:database, :username, :password, :host, :socket) cmds = ['mysqldump', "-u #{options[:username]}", "--password='#{options[:password]}'", options[:socket].present? ? "-S #{options[:socket]}" : "-h #{options[:host]}", options[:database], name, "| gzip > #{dumpfile}"] cmd = cmds.join(' ') puts "executing: #{cmd.gsub(/(--password)=[^ ]*/, '\1=xxxx')}" system(cmd) or raise "command failed!" end def up legacy_tables = [ :zzz_acct_areas, :acct_contact_roles, # ...ç¥... ] legacy_tables.select! do |table_name| table_exists?(table_name) end # backup tables by mysqldump timestamp = Time.now.utc.strftime('%Y%m%d%H%M%S') legacy_tables.each do |table_name| backup_table table_name, timestamp end # rename foreign keys before drop tables legacy_tables.each do |table_name| foreign_keys(table_name).each do |fk| remove_foreign_key table_name, name: fk.name end end # then drop tables legacy_tables.each do |table_name| drop_table table_name end end def down puts "rollback of DropLegacyTables does't restore legacy tables." end end
ããã§ã¯å¿µã®ããåé¤åã«ãã¼ãã«æ¯ã«mysqldump
ã§ããã¯ã¢ããããã¦ãã¾ãã
ã¾ããä»ã®ãã¼ãã«ã¨å¤é¨ãã¼å¶ç´ã®ãªã¬ã¼ã·ã§ã³ããããã¼ãã«ãããã®ã§ããããå¤é¨ãã¼å¶ç´ã¯å
ã«remove_foreign_key
ã§åé¤ãã¦ãã¾ãã
æå¾ã«drop_table
ã§ãã¼ãã«ãåé¤ãããã¨ã§ãä¸è¦ãã¼ãã«ã®åæ¸ã¯å®äºã§ãã
migration ãã¡ã¤ã«ãæ´çãã
ãã¦ãä¸è¦ãã¼ãã«ã®åé¤ã¯çµãã£ããã®ã®ãdb/migrate/
以ä¸ã«ã¯å餿¸ã¿ã®ãã¼ãã«ã®åãå«ãã¦å¤§éã®migrationãã¡ã¤ã«ãæ®ã£ã¦ãã¾ããã
ãã®æç¹ã§ããã500åå¼±ã®migrationãã¡ã¤ã«ããã£ã¦ãåã«æ°ãå¤ãã ããªãããã»ã©å®³ã¯ç¡ãã®ã§ããã
- æ°ããDBãä½ã£ã¦
rake db:migrate
ããã¨migrationãã¡ã¤ã«ç¾¤ã®è²ããªã¨ããã§ã¨ã©ã¼ãåºã¦åããªã
ã¨ããåé¡ããã£ã¦ãæ°ããåå ããã¨ã³ã¸ãã¢ãæå
ã«éçºç°å¢ãæ§ç¯ããã¨ãã«ã¯ãä»ã®æ¢ã«åãã¦ããç°å¢ã®DBããmysqldump
ãã¦ããã£ã¦ãããããªãã¨ããç¶æ³ã§ããã
ãã®ã¨ã©ã¼ã®åå ã®ã»ã¨ãã©ã¯åç´ã§ãä¾ãã°migrationãã¡ã¤ã«ã«
class AddPricingPlanIdToUsers < ActiveRecord::Migration def up add_column :users, :pricing_plan_id, :integer plan_enterprise = PricingPlan.where(label: 'enterprise_jp_v1').first User.where(role: User::Role::STANDARD).find_each do |user| user.pricing_plan_id = plan_enterprise.id user.save! end end def down remove_column :users, :pricing_plan_id end end
ã®ããã«ãã«ã©ã ã追å ããã¤ãã§ã«ã¢ãã«ã¯ã©ã¹ã使ã£ã¦å¤ãè¨å®ãã¦ããã¨ããã§ã²ã£ããã£ã¦ãã¾ããã ãããæ¸ãã彿ã¯åãã¦ããã¯ãã§ããããã®å¾ã®çµç·¯ã§ã¯ã©ã¹ãã®ãã®ãç¡ããªã£ãããã¦åããªãã³ã¼ãã«ãªã£ã¦ãã¾ã£ãã¨ããããã§ãã
migrationãã¡ã¤ã«ã§å°æ¥å¤ããããã¯ã©ã¹ã宿°ã使ãã®ã¯æªãã³ã¼ãã§ãæ¬å½ã¯
def up add_column :users, :pricing_plan_id, :integer plan_enterprise_id = connection.select_value('SELECT id FROM pricing_plans WHERE label = "enterprise_jp_v1"') role = 1 # User::Role::STANDARD execute <<-SQL UPDATE users SET users.pricing_plan_id = #{plan_enterprise_id} WHERE role = #{role} SQL end
ã®ããã«çã®SQLã§è¨å®ãããããªã³ã¼ãã«ãã¹ãã§ããã
ã¨ã¯è¨ãæ¢ã«ãã500åè¿ãmigrationãã¡ã¤ã«ã®ãã¡ãç¾å¨åããªãã³ã¼ããä½ç®æããã£ã¦ãæåããå ¨ã¦éãããã«ä¿®æ£ããã®ã¯ãããªãã«æéããããããã§ãã
ããããå¤ãmigrationãã¡ã¤ã«ã®ã³ã¼ããè¦ããã¨ã¯çµé¨ä¸ã»ã¨ãã©ãªããæ®ã£ã¦ãã¦ãèå¤å¦çãªä¾¡å¤ããããããªãã®ã§ãæéãããã¦ä¿®æ£ããã»ã©ã§ããªãã¨èãã¦ãä»åãããã䏿°ã«åé¤ãããã¨ã«ãã¾ããã
åé¤ããã¨è¨ã£ã¦ãdb:migrate
ããã¨ãã«ã¡ããã¨DBãææ°ã®ç¶æ
ã«ãªãããã«ãããã®ã§ãåé¤ãã代ããã«ææ°ã®db/schema.rb
ç¸å½ã®migrationãã¡ã¤ã«ãç¨æãããã¨ã«ãã¾ãã
ã¾ãã¯æ¬çªã®ãµã¼ãã¼ã§rake db:schema:dump
ãå®è¡ãã¦ææ°ã®db/schema.rb
ãåå¾ãã¾ãã
ActiveRecord::Schema.define(version: 20180626172837) do create_table "active_admin_comments", force: :cascade do |t| t.string "resource_id", limit: 255, null: false t.string "resource_type", limit: 255, null: false # ...ç¥...
ãã®define
å
ãææ°ã®ãã¼ãã«ã®ã¹ãã¼ãæ
å ±ã«ãªã£ã¦ãã¦ããã®ã³ã¼ãã¯ãã®ã¾ã¾migrationãã¡ã¤ã«ã§ä½¿ããã®ã§ããããæ°ãã«ä½ã£ãmigrationãã¡ã¤ã«ã®ä¸ã«ã³ãã¼ãã¾ãã
class SchemaSnapshot < ActiveRecord::Migration def up return if table_exists? :active_admin_comments create_table "active_admin_comments", force: :cascade do |t| t.string "resource_id", limit: 255, null: false t.string "resource_type", limit: 255, null: false # ...ç¥...
ããã§æåã«ãã¼ãã«ãæ¢ã«åå¨ãããã¹ãããããå¦çãå ¥ãã¦ããã¾ãã
ãã®æ°ããmigrationãã¡ã¤ã«ã¯æ°ãã«DB使ãã¦db:migrate
ããã¨ãã®ããã®ãã®ã§ãæ¢åã®DBãããç°å¢ã§ã¯ããã§ã¹ããããããããã«ãã¾ãã
ããã§æ°ããç°å¢ã§ãã®migrationãã¡ã¤ã«ãå®è¡ãããã¨db/schema.rb
ç¸å½ã®ç¶æ
ã«ãªãã¨ããã¾ã§é²ã¿ã¾ãããdb/schema.rb
ã«ã¯è¼ããªããã®ã®åä½ã«å¿
è¦ãªæ
å ±ãå¤ãmigrationãã¡ã¤ã«ã«æ®ã£ã¦ããå ´åãããã¾ãã
å ·ä½çã«ã¯ãçµµæå対å¿ã®ããã«ä¸é¨ã«ã©ã ãutf8mb4ã«å¤æ´ãã¦ããããå¿ è¦ãªåæã¬ã³ã¼ãããã¼ãã«ã«æå ¥ããããã¹ãã¢ããã¡ã³ã¯ã·ã§ã³ãå®ç¾©ãããã¨ãã£ãã³ã¼ãã§ãã
ããããå¤ãmigrationãã¡ã¤ã«ããæ´ãåºãã¦ãæ°ããmigrationãã¡ã¤ã«ã®ä¸ã«
# set utf8mb4 columns execute "ALTER TABLE users CHANGE `username` `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" execute "ALTER TABLE users CHANGE `comment` `comment` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" # ...ç¥... # init membership_roles execute <<-SQL INSERT INTO membership_roles (id, name, ancestry, receive_emails, created_at, updated_at, is_inheritable, is_root_organization_only, type) VALUES (1, 'owner', NULL, TRUE, NOW(), NOW(), TRUE, TRUE, 'MembershipRole::Organization'), (2, 'admin', '1', TRUE, NOW(), NOW(), FALSE, FALSE, 'MembershipRole::Organization'), (3, 'member', '1/2', FALSE, NOW(), NOW(), FALSE, FALSE, 'MembershipRole::Organization') SQL # ...ç¥...
ã®ããã«æä½æ¥ã§ç§»æ¤ãã¦ãããããä¸ã¤ã®å·¨å¤§ãªmigrationãã¡ã¤ã«ã宿ãã¾ããã
ãããå¤ãmigrationãã¡ã¤ã«ãå ¨åé¤ãã代ããã«é ç½®ããã°å®äºã§ãã
ã¡ãªã¿ã«ãã®å¤ãmigrationãã¡ã¤ã«ãæ¨ã¦ã¦db/schema.rb
ããæ°ããmigrationãã¡ã¤ã«ãä½ãã®ã¯ããããsquasher gemã§ãã§ãããã ã£ãã®ã§ãããããèªä½ã¯æä½æ¥ã§ãããã§ããã®ã¨ãdb/schema.rb
ã«è¼ããªãæ
å ±ã®ç§»æ¤ã¯ã©ã®ã¿ã¡å¿
è¦ã ã£ãã®ã§ãä»åã¯ãããã¦æä½æ¥ã§æ¸ã¾ãã¾ããã
ãã£ã¨ç´ ç´ãªå
容ã®migrationã§ããã°squasher gemã§ã¾ã¨ããæ¹ãç°¡åããããã¾ããã
æå¾ã«
Kaizenã®Railsãªãã¸ããªã®ä¸ã¤ã§ã¯ä»åãããªé¢¨ã«å¤ããã¼ãã«ãmigrationãã¡ã¤ã«ã®æ´çãè¡ã£ã¦ãã¾ããã ç´3åã®1ã®ãã¼ãã«ã¨å¤§éã®migrationãã¡ã¤ã«ãæ¶ããã®ã§ãéåã¨ãã£ããããããã«æãã¾ãã
åä½ã«æ¯éã¯ç¡ãããã©ãå¤ãã¦æ´çããæ¹ããããã®ã¯ãã¼ãã«å¨ãã«éããæ¾ç½®ããã¡ã§ãèç©ãã¦ããã¨å¾ã ã«ãæ°ããä½ããä½ãéã«éçºãã¥ããç°å¢ã«ãªã£ã¦ãã¾ãã¾ãã ãã¡ããæ°æ©è½ã®éçºãéè¦ãªã®ã§ããããã®ä¸æ¹ã§ããããéå»ã®è² åµããã©ã³ã¹è¯ãæ¸ ç®ãã¦ç¶ç¶çã«éçºããããç°å¢ãä½ããã¨ã大äºã§ãã
å®éã®ã¨ããä»ç¤¾ããã§ã¯ããããã¨ããã«ã¯ãªããªãå·¥æ°ãåããªãã®ã§ããããã®ç¹ããããã£ã¦éå»ã®è² åµãè§£æ¶ããããã®å·¥æ°ããã£ãã確ä¿ã§ããã®ã¯ãKaizen Platformããã®ç´ æµãªã¨ããã®ä¸ã¤ã¨æãã¾ãã