Trucos Avanzados en MySQL

download Trucos Avanzados en MySQL

of 3

description

Trucos Avanzados en MySQL

Transcript of Trucos Avanzados en MySQL

Clonar registros enmysql Si necesitas una funcin para clonar registros, aqu tienes unas. La idea es sencilla: usar SQL para clonar un registro. En esencia es algo as:

INSERT INTO tabla (SELECT * FROM tabla WHERE id=..)El problema es que la SQL anterior no funciona si tienes un campo clave (99% de las tablas, o un campo nico). As que toca refinar mas la funcin.

function mysql_clonar_registro ( $tabla, $clave ) {

// limpieza parmetros $tabla= mysql_real_escape_string($tabla); $clave= mysql_real_escape_string($clave);

// obtener lista de campos, no nicos $rsCampos = mysql_query("SHOW COLUMNS FROM $tabla"); $campos= array(); $campoClave =""; while ( $campo = mysql_fetch_array($rsCampos) ){

if ( $campo["Key"] == "PRI" ){ $campoClave = $campo[0]; } $campos[] = $campo["Key"] == "PRI" || $campo["Key"] == "UNI" ? "NULL": $campo[0]; } mysql_free_result ( $rsCampos );

// clonar el registro mediante una SQL if ( $campoClave && count($campos)>0 ) { $SQL = sprintf( "INSERT INTO $tabla ( SELECT %s FROM $tabla WHERE %s='%s' )", implode(",",$campos), $campoClave, $clave ); mysql_query ($SQL); return mysql_affected_rows(); } return false;}

Recuperar contrasea rootmysql Si alguna vez has olvidado, extraviado, o no fui yo quien la puso la contrasea de administracin de mysql, es decir la contrasea del usuario root, aqu tienes seis pasitos para recuperarla.Otra de las rarezas de mysql es que toda la informacin de mysql se guarda en una base de datos llamada mysql (si uno lo piensa bien, es tan raro como guardar la combinacin de la caja fuerte..en la caja fuerte). Si podemos seleccionar esa base de datos, solo tenemos que modificar la tabla de usuarios. Pero, como acceder la base de datos si no tenemos usuarios? Fcil, ya que el servidor MSQL tiene una opcin por la que es capaz de arrancar sin tener en cuenta la tabla de privilegios. Una opcin que solo debe usarse en casos de mximo necedad.Bueno, pues vamos a solucionar el problema con estos seis pasos:1. Para el servidor mysqld con: 2. sudo /etc/init.d/mysql stop3. Inicia el servidor mysql, en background, con la opcin skip-grant-tables. Esto activa Mysql sin cargar las tablas de privilegios. 4. sudo mysqld --skip-grant-tables &5. Abre el cliente mysql con estos datos:< 6. mysql -uroot mysqlCon esta orden entras al cliente con la cuenta root y seleccionas la base de datos mysql, donde se guarda toda la configuracin del servidor. Los siguientes dos pasos se realizan dentro de este cliente.7. Cambia la contrasea usando este comando SQL: 8. mysql> UPDATE user SET Password=PASSWORD('nuevacontrasea')9. WHERE User='root';10. Refresca los privilegios con el siguiente comando SQL y cierra el cliente: 11. mysql> FLUSH PRIVILEGES; ..12. mysql> exit13. Reinicia el servidor con 14. /etc/init.d/mysql restartLos pasos 1,2 y 6 funcionan en UBUNTU. Fulltext de varias columnas (rarezas MySQLII) Si el anterior post comentbamos algunas rarezas de mysql con los campos timestamp, los ndices FULLTEXT, tampoco se quedan cortos. Este tipo de ndices indexan cada palabra del campo, normalmente un texto, con el objeto de facilitar las bsquedas por palabras. Luego se utiliza el operando SQL: MATCH (columnas) AGAINST (expresion).Hasta all todo normal. Imaginaos que tengo indexados dos campos, titulo y texto, cada con su FULLTEXT. como tengo que realizar la bsqueda sobre los dos campos?Lo lgico es pensar que MATCH(titulo,texto) AGAINST('lorem') bastara, pero no es as. Lo que hay que hacer es:1. Definir un solo ndice fulltext con las dos columnas, mediante SQL ya que phpmyadmin no lo permite: ALTER TABLE tbl ADD FULLTEXT combinado(titulo,texto).2. Debes repetir en MATCH todos los campos indexados. Es decir: MATCH(titulo,texto) AGAINST ("LOREM")Evidentemente la consulta SQL final ser tan largo como:SELECT *, MATCH(titulo,texto) AGAINST("LOREM") as ratio FROM bs WHERE MATCH(titulo,texto) AGAINST("LOREM") ORDER by ratio DESC Para terminar, apunto algunas cosillas mas sobre fulltext:- con pocos registros en la tabla, MATCH, siempre devuelve cero.- hemos llamado al ndice combinado (1 paso), pero ese nombre no se utiliza para nada.- con muchos resultados positivos (una palabras que aparezca en todos los registros) MATCH tambin devuelve cero.A pesar de sus peculiaridades los campos FULLTEXT son muy tilespero raritosdos timestamp en unregistro Si algunos creis que el PHP es rarito para algunas cosillas, es que no habis trabajado contra un MYSQL (y aqu el contra esta usado en sentido literal).A la hora de definir los campos de una tabla, existe un tipo de campo llamado timestamp para guardar una marca de tiempo. Podemos usarlo para saber cuando se ha creado un registro, o cuando se ha modificado. Pero, podemos tener dos campos timestamp, uno para la hora de creacin y otro para la modificacin? Pues si, aunque lo configuracin resulta un tanto esotrica:1. el campo para la modificacin tiene que tener el atributo on update CURRENT TIMESTAMP.2. el campo para la hora creacin no tiene que tener el atributo anterior, y contra toda lgica no tiene como valor por defecto CURRENT STAMP (lo normal, si no hay un campo de modificados) sino NONE. Cuando insertes registros debes usar la funcin SQL now():INSERT INTO tabla. (CREADO,) VALUES (now(),..)Corre el rumor de que si defines el campo creacin con el valor por defecto NULL ( y el campo admite NULL) al insertar un registro sin fecha, el valor NULL se sustituye por la fecha actual. Bueno, si lo haces con phpmyadmin, es cierto, pero se trata de un truco, ya que la SQL que genera phpmyadmin introduce la funcin NOW. Pero con una consulta directa no va a funcionar.Hubiera sido mas fcil y lgico que MYSQL admita directamente los dos campos, pero el MYSQL es asn ..de rarito.