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' }
Agosto 13th, 2008 at 12:07 pm
Atención cuidado con los copy&paste y los > y los < que me los cuela el wordpress.
Febrero 7th, 2010 at 11:22 am
Great information is very interesting. I’m Kitty and learning SEO from New York.
Febrero 7th, 2010 at 2:33 pm
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???…
Febrero 7th, 2010 at 3:28 pm
@mark: go ahead.
Agosto 14th, 2012 at 3:48 pm
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.
Abril 6th, 2015 at 4:03 am
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.