Thinking on hiring me?

Please read

Fernando Guillén

a Freelance Web Developer

cabecera decorativa

software development as an artistic expression

Ruby on Rails: definir el tamaño de un índice MySQL en las migraciones

Revisando el log de tus queries te puedes encontrar que si estás buscando registros por un campo VARCHAR te salte un warning de “long key length“.

Esto es porque el índice que has puesto en este campo VARCHAR es muy grande, aunque MySQL soporta índices de hasta 1000 bytes si son muy grandes pueden ralentizar las búsquedas.

La solución está en limitar el tamaño del índice a un número bastante pequeño.

En MySQL esto se indica así:

ALTER TABLE mi_tabla ADD INDEX ( campo_del_indice(4) )

ó también:

CREATE  INDEX `nombre_del_indice` ON mi_tabla (`campo_del_indice`(4))

El problema es que si estamos usando ‘migrations‘ de Rails y queremos ser puristas nos encontramos con que la sintaxis estándar de las migraciones de Rails no soporta el campo ‘longitud’.

Como bien dice Jaime Iniesta existe un parche que da soporte a las migraciones para admitir el campo ‘length’.

Yo sin embargo he preferido no tocar el código de mis gemas y meter este fichero (rails_migraions_hack.rb) en el ‘/lib‘ de mi aplicación:

module ActiveRecord
  module ConnectionAdapters # :nodoc:
    module SchemaStatements
      def add_index(table_name, column_name, options = {})
        column_names = Array(column_name)
        index_name   = index_name(table_name, :column => column_names)
 
        if Hash === options # legacy support, since this param was a string
          index_type = options[:unique] ? "UNIQUE" : ""
          index_name = options[:name] || index_name
          index_length = options[:length] ? "(#{options[:length]})" : nil # only mysql
        else
          index_type = options
        end
        quoted_column_names = column_names.map { |e| quote_column_name(e) }.join(", ")
        # execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} (#{quoted_column_names})"
        sql = "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{table_name} (#{quoted_column_names}#{index_length})"
        p "SQL: #{sql}"
        execute sql
      end
    end
  end
end

Y cargarlo con un:

require 'rails_migrations_hack'

En mi environment.rb.

Funciona perfectamente y vemos como saca por pantalla las querys de las creaciones de índices con cosas como esta:

"SQL: CREATE  INDEX `idx_forums_forums_nicetitle` ON forums_forums (`nicetitle`(4))"

Es interesante consultar toda la discusión en la lista de ror-es.

Actualizado (2008-08-13):

Al parecer no estan cubiertas todas las posibilidades.

En el caso de estar creando un índice compuesto el atributo length se lo asigna al último campo y esto puede no ser lo adecuado:

add_index :tabla, [:campo1, :campo2], :name => 'idx_tabla1', :length => '10'

lo que intenta es hacer:

CREATE  INDEX `idx_tabla1` ON tabla (`campo1`, `campo2`(10))

Si el campo varchar que queremos limitar es el primero la hemos cagado..

Habría que intentar modificar la sintaxis del length para que coja algo como esto:

add_index :tabla, [:campo1, :campo2], :name => 'idx_tabla1', :length => { :campo1 => '10' }
6 Comments to “Ruby on Rails: definir el tamaño de un índice MySQL en las migraciones”
  1. fguillen Says:

    Atención cuidado con los copy&paste y los > y los < que me los cuela el wordpress.

  2. Kitty Love Says:

    Great information is very interesting. I’m Kitty and learning SEO from New York.

  3. Mark Says:

    Found your blog on Ask and was so glad i did. That was a warming read. I have a small question.Is it alright if i send you an email???…

  4. fguillen Says:

    @mark: go ahead.

  5. SDXC memory card Says:

    I was barely in college and I started to sell things on eBay. Stuff that really wasn’t worth my time to even list but hey, when you’re in college, you can get several meals out of $10. I had a friend who showed me how to use HTML tags to jazz up my listings a little. This really interested me and I started to teach myself more about this. I liked it so much that I changed my minor to a web design and development minor. That’s how I got started 10 years ago and I’ve grown and learned a lot since then. In the last 10 years, I have built many web sites. I’ve built sites for small Mom & Pop shops, I’ve built e-commerce web sites and I’ve built web sites for international organizations. Every site that I build I still feel like I learn so much on. My web design skills improve, my efficiency improves, my expectations are more accurate, my organization improves and most importantly, the final product improves.

  6. japan karatsu shirohake 4 Says:

    It’s truly a nice and useful piece of information. I am satisfied that you
    just shared this useful information with us.
    Please stay us informed like this. Thanks for sharing.

Leave a comment

a Freelance Web Developer is proudly powered by WordPress
Entries (RSS) and Comments (RSS).

Creative Commons License
Fernando Guillen's blog by Fernando Guillen is licensed under a Creative Commons Attribution-NoDerivs 3.0 Unported License.