Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

bien planteado para manejar claves foraneas y FULLTEXT

Estas en el tema de bien planteado para manejar claves foraneas y FULLTEXT en el foro de Mysql en Foros del Web. Hola buenas, tengo en la base de datos una tabla en la que quiero hacer una búsqueda de texto completo. Pero esta tabla esta relacionada ...
  #1 (permalink)  
Antiguo 21/03/2013, 11:58
 
Fecha de Ingreso: diciembre-2012
Mensajes: 21
Antigüedad: 11 años, 5 meses
Puntos: 0
bien planteado para manejar claves foraneas y FULLTEXT

Hola buenas,

tengo en la base de datos una tabla en la que quiero hacer una búsqueda de texto completo. Pero esta tabla esta relacionada con otras. Y lo que habia pensado era hacer la tabla "archivos" de tipo InnoDB para poder relacionar con las demas, y después hacer una tabla "archivosBusqueda" de tipo MySAM que se borraria a trabes de la aplicacion cada vez que se borre un archivo por parte de cualquier otra que este asociada a la pimera tabla con el borrado en cascada.

Está bien planteado? O hay alguna razón por la que otra opción sea mejor?

Muchas gracias!
  #2 (permalink)  
Antiguo 21/03/2013, 13:14
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 4 meses
Puntos: 447
Respuesta: bien planteado para manejar claves foraneas y FULLTEXT

Hola franroa:

El planteamiento que haces creo que es correcto, sin embargo tengo una duda en cuanto a esto que pones:

Cita:
hacer una tabla "archivosBusqueda" de tipo MySAM que se borraria a trabes de la aplicacion cada vez que se borre un archivo por parte de cualquier otra que este asociada a la pimera tabla con el borrado en cascada.
El concepto de eliminación en cascada sólo aplica sobre tablas InnoDB, cuando defines llaves foráneas entre dos o más tablas, sin embargo con tablas MyISAM no lo puedes hacer... también tengo dudas en cuando a hacerlo a través de una aplicación, en realidad tampoco creo que sea conveniente, pues te expones a que cualquier persona que tenga acceso al servidor haga modificaciones a la BD sin que te des cuenta y por lo tanto la tabla quede desactualizada. Lo ideal es que dejes que el DBMS se encargue de hacer la eliminación o actualización de tu tabla MyISAM a partir de lo que haces en tu tabla InnoDB. Una idea sería mediante un trigger, checa estas ligas, creo que ahí se explica bastante bien a lo que me refiero.


http://www.joinfu.com/2006/02/emulat...myisam-tables/

http://stackoverflow.com/questions/5...storage-engine

Saludos
Leo.
  #3 (permalink)  
Antiguo 21/03/2013, 13:41
 
Fecha de Ingreso: diciembre-2012
Mensajes: 21
Antigüedad: 11 años, 5 meses
Puntos: 0
Respuesta: bien planteado para manejar claves foraneas y FULLTEXT

Sisi, lo de las limitaciones de MySAM lo conocía.
Quería decir que tengo las tablas:

archivos (InnoDB)
usuarios (InnoDB)

Y la union de ellas seria archivosUsuarios (InnoDB)
Y hay varias tablas mas relacionadas con la tabla "archivos"

Pero el campo "descripcion" de los archivos sería fulltext. Asi que pensaba hacer una tabla archivosBuscar (MySAM) donde estaria solo la descripcion del id del archivo.


El problema que le veía al planteamiento es que tengo que mandar en cada busqueda cada id del campo descripcion en el que se haya encontrado algo. Y le veia ahi un fallo.
Pero ahora que me dices lo de los triggers es verdad que no lo tenía en cuenta. Error de novato .

Muchas gacias
  #4 (permalink)  
Antiguo 21/03/2013, 13:48
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: bien planteado para manejar claves foraneas y FULLTEXT

Cita:
Pero el campo "descripcion" de los archivos sería fulltext.
FULLTEXT no es un tipo de campo, sino de índice, el cual no aplica a las tablas InnoDB.
No confundir.

Tal vez te estés refiriendo a un campo TEXT. que es otra cosa, y me parece algo excesivo para una columna que contiene meras descripciones.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #5 (permalink)  
Antiguo 21/03/2013, 16:04
 
Fecha de Ingreso: diciembre-2012
Mensajes: 21
Antigüedad: 11 años, 5 meses
Puntos: 0
Respuesta: bien planteado para manejar claves foraneas y FULLTEXT

Cierto, no he hablado con propiedad. Quería decir índice.

He mirado la pagina que me has recomendado y resolvi hacer este trigger:


DELIMITER |

CREATE TRIGGER deletecascade AFTER DELETE ON files
FOR EACH ROW
BEGIN
DELETE FROM portalfiles WHERE pfFileID = old.fileID;
DELETE FROM userfiles WHERE ufFileID = old.fileID;
DELETE FROM subjectfiles WHERE sfFileID = old.fileID;
END
|

DELIMITER ;


Me lanza el error:

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DELIMITER #

CREATE TRIGGER deletecascade AFTER DELETE ON files
FOR EACH ROW
' at line 1
  #6 (permalink)  
Antiguo 21/03/2013, 16:18
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 4 meses
Puntos: 447
Respuesta: bien planteado para manejar claves foraneas y FULLTEXT

Hola franroa:

El código que pones no tienen ningún error, además menciona un caracter # el cual ni siguiera pones en el código... Checa este script, creo las cuatro tablas que mencionas, con un solo campo, inserto datos en las cuatro tablas, creo el trigger, elimino un elemento de la tabla files y se eliminan de las otras tablas, no hay ningún error en el código:

Código MySQL:
Ver original
  1. mysql> SELECT * FROM files;
  2. +--------+
  3. | fileID |
  4. +--------+
  5. |      1 |
  6. |      2 |
  7. |      3 |
  8. +--------+
  9. 3 rows in set (0.00 sec)
  10.  
  11. mysql> SELECT * FROM portalfiles;
  12. +----------+
  13. | pfFileID |
  14. +----------+
  15. |        1 |
  16. |        2 |
  17. |        3 |
  18. +----------+
  19. 3 rows in set (0.00 sec)
  20.  
  21. mysql> SELECT * FROM userfiles;
  22. +----------+
  23. | ufFileID |
  24. +----------+
  25. |        1 |
  26. |        2 |
  27. |        3 |
  28. +----------+
  29. 3 rows in set (0.00 sec)
  30.  
  31. mysql> SELECT * FROM subjectfiles;
  32. +----------+
  33. | sfFileID |
  34. +----------+
  35. |        1 |
  36. |        2 |
  37. |        3 |
  38. +----------+
  39. 3 rows in set (0.00 sec)
  40.  
  41. mysql> DELIMITER |
  42. mysql> CREATE TRIGGER deletecascade AFTER DELETE ON files
  43.     -> FOR EACH ROW
  44.     -> BEGIN
  45.     -> DELETE FROM portalfiles WHERE pfFileID = old.fileID;
  46.     -> DELETE FROM userfiles WHERE ufFileID = old.fileID;
  47.     -> DELETE FROM subjectfiles WHERE sfFileID = old.fileID;
  48.     -> END
  49.     -> |
  50. Query OK, 0 rows affected (0.05 sec)
  51.  
  52. mysql> DELIMITER ;
  53. mysql> DELETE FROM files WHERE fileID = 1;
  54. Query OK, 1 row affected (0.04 sec)
  55.  
  56. mysql> SELECT * FROM files;
  57. +--------+
  58. | fileID |
  59. +--------+
  60. |      2 |
  61. |      3 |
  62. +--------+
  63. 2 rows in set (0.00 sec)
  64.  
  65. mysql> SELECT * FROM portalfiles;
  66. +----------+
  67. | pfFileID |
  68. +----------+
  69. |        2 |
  70. |        3 |
  71. +----------+
  72. 2 rows in set (0.00 sec)
  73.  
  74. mysql> SELECT * FROM userfiles;
  75. +----------+
  76. | ufFileID |
  77. +----------+
  78. |        2 |
  79. |        3 |
  80. +----------+
  81. 2 rows in set (0.00 sec)
  82.  
  83. mysql> SELECT * FROM subjectfiles;
  84. +----------+
  85. | sfFileID |
  86. +----------+
  87. |        2 |
  88. |        3 |
  89. +----------+
  90. 2 rows in set (0.00 sec)

Revisa bien qué es lo que trataste de ejecutar y qué es lo que postaste.

Saludos
Leo.
  #7 (permalink)  
Antiguo 21/03/2013, 17:07
 
Fecha de Ingreso: diciembre-2012
Mensajes: 21
Antigüedad: 11 años, 5 meses
Puntos: 0
Respuesta: bien planteado para manejar claves foraneas y FULLTEXT

Es eso lo que qería hacer. Pero definitivamente hay algo cuando defino los triggers que no hago bien... Y no doy con ello.

Por ejemplo, esto me lanza el mismo error:


Código MySQL:
Ver original
  1. CREATE TABLE files(
  2. fPath TEXT NOT NULL,/*UNIQUE*/
  3. fDescription VARCHAR(250) NOT NULL,
  4. fName VARCHAR (20) NOT NULL,T NULL,
  5. fUploader INT NOT NULL,
  6. PRIMARY KEY (fileID),
  7.  
  8.  
  9. CREATE TABLE filedescriptions(
  10. fileID BIGINT NOT NULL,
  11. fName VARCHAR (20) NOT NULL,
  12. fDescription VARCHAR(250) NOT NULL,
  13. PRIMARY KEY (fileID),
  14. FULLTEXT KEY description (fName, fDescription)
  15. )ENGINE=MyISAM;
  16.  
  17.  
  18.  
  19.  
  20. DELIMITER ;;
  21.     INSERT INTO filedescriptions (fileID, fName, fDescription)
  22.         VALUES (new.fileID, new.fName, new.fDescription);
  23.   END;;
  24.  
  25.  
  26.     IF (old.fileID!= new.fileID) or (old.fDescription!= new.fDescription)
  27.     THEN
  28.         UPDATE filedescriptions
  29.             SET fileID=new.fileID,
  30.                 fDescription=new.fDescription,
  31.                 fileID=new.fileID
  32.         WHERE fileID=old.fileID;
  33.     END IF;
  34.   END;;
  35.  
  36.  
  37.     DELETE FROM filedescriptions WHERE fileID = old.fileID;
  38.   END;;
  39.  
  40. DELIMITER ;

Ya siento robaros el tiempo. Pero llevo horas con esto, y de verdad que no tengo ni idea de que puede ser.
  #8 (permalink)  
Antiguo 22/03/2013, 03:15
 
Fecha de Ingreso: diciembre-2012
Mensajes: 21
Antigüedad: 11 años, 5 meses
Puntos: 0
Respuesta: bien planteado para manejar claves foraneas y FULLTEXT

Bueno, he estado mirando en la pagina oficial de MySQL y he intentado implementar el trigger que tienen ahi como ejemplo. Me vuelve a lanzar el mismo error. Así que no es fallo de sintaxis.

Tengo la version 5.0 del MySQL. Tengo entendido que a partir de esta se pueden usar los triggers. Aunque tal vez use otra sintaxis. O no me queda mas remdio que actualizar?...
  #9 (permalink)  
Antiguo 22/03/2013, 09:10
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 4 meses
Puntos: 447
Respuesta: bien planteado para manejar claves foraneas y FULLTEXT

Hola de nuevo franroa:

Creo que debes poner un poco más de atención a lo que lees en los manuales de MySQL o lo que ponemos en el Foro, porque estás cometiendo errores infantiles con tu código. Vayamos por partes:

Código:
CREATE TABLE files(
fileID BIGINT NOT NULL AUTO_INCREMENT,
fPath TEXT NOT NULL,/*UNIQUE*/
fDescription VARCHAR(250) NOT NULL,
fName VARCHAR (20) NOT NULL,T NULL,
fUploader INT NOT NULL,
PRIMARY KEY (fileID),
)ENGINE=INNODB;
Esta sentencia está mal por el código que está marcado en rojo, no sé si copiaste mal la sentencia o se cortó alguna parte, pero en la primer parte NO ESTÁS DEFINIENDO NINGÚN CAMPO, después solo pones T NULL, eso no corresponde a ninguna declaración, MySQL toma la coma como separador de la definición de cada campo, por lo tanto, toma T como un campo, pero no colocas ningún tipo de datos, ni nada por el estilo. En la última parte, después del PRIMARY KEY (fileID) NO DEBES COLOCAR NINGUNA COMA, porque te repito indica separador de campos... la sentencia debería quedar así:

Código MySQL:
Ver original
  1. CREATE TABLE files(
  2. fPath TEXT NOT NULL,
  3. fDescription VARCHAR(250) NOT NULL,
  4. fName VARCHAR (20) NOT NULL,
  5. fUploader INT NOT NULL,
  6. PRIMARY KEY (fileID)

Siguiendo con los errores:

Código:
DELIMITER ;;
CREATE TRIGGER 'insert_file' AFTER INSERT ON 'files' FOR EACH ROW BEGIN
    INSERT INTO filedescriptions (fileID, fName, fDescription)
        VALUES (new.fileID, new.fName, new.fDescription);
  END;;
checa esta liga:

http://dev.mysql.com/doc/refman/5.0/es/legal-names.html

Cita:
El carácter de encomillado de identificador es el acento grave: ('`'):
la comilla, tal como la colocas indica una CADENA DE TEXTO, para definir los nombres de los objetos de BD debes utilizar el ACENTO GRAVE (`) o en su defecto omitir este caracter...

Tu sentencia debería quedar así:

Código MySQL:
Ver original
  1. DELIMITER ;;
  2.     INSERT INTO filedescriptions (fileID, fName, fDescription)
  3.         VALUES (new.fileID, new.fName, new.fDescription);
  4.   END;;

o con el acento grave:

Código MySQL:
Ver original
  1. DELIMITER ;;
  2.     INSERT INTO filedescriptions (fileID, fName, fDescription)
  3.         VALUES (new.fileID, new.fName, new.fDescription);
  4.   END;;

Este código se ejecuta perfectamente en un servidor 5.5:

Código MySQL:
Ver original
  1. mysql> CREATE TABLE files(
  2.     -> fileID BIGINT NOT NULL AUTO_INCREMENT,
  3.     -> fPath TEXT NOT NULL,
  4.     -> fDescription VARCHAR(250) NOT NULL,
  5.     -> fName VARCHAR (20) NOT NULL,
  6.     -> fUploader INT NOT NULL,
  7.     -> PRIMARY KEY (fileID)
  8.     -> )ENGINE=INNODB;
  9. Query OK, 0 rows affected (0.09 sec)
  10.  
  11. mysql> CREATE TABLE filedescriptions(
  12.     -> fileID BIGINT NOT NULL,
  13.     -> fName VARCHAR (20) NOT NULL,
  14.     -> fDescription VARCHAR(250) NOT NULL,
  15.     -> PRIMARY KEY (fileID),
  16.     -> FULLTEXT KEY description (fName, fDescription)
  17.     -> )ENGINE=MYISAM;
  18. Query OK, 0 rows affected (0.07 sec)
  19.  
  20. mysql> DELIMITER ;;
  21. mysql> CREATE TRIGGER insert_file AFTER INSERT ON files FOR EACH ROW BEGIN
  22.     ->     INSERT INTO filedescriptions (fileID, fName, fDescription)
  23.     ->         VALUES (new.fileID, new.fName, new.fDescription);
  24.     ->   END;;
  25. Query OK, 0 rows affected (0.07 sec)
  26.  
  27. mysql> DELIMITER ;;
  28. mysql> CREATE TRIGGER update_file AFTER UPDATE ON files FOR EACH ROW BEGIN
  29.     ->     IF (old.fileID!= new.fileID) OR (old.fDescription!= new.fDescription)
  30.  
  31.     ->     THEN
  32.     ->         UPDATE filedescriptions
  33.     ->             SET fileID=new.fileID,
  34.     ->                 fDescription=new.fDescription,
  35.     ->                 fileID=new.fileID
  36.     ->         WHERE fileID=old.fileID;
  37.     ->     END IF;
  38.     ->   END;;
  39. Query OK, 0 rows affected (0.07 sec)
  40.  
  41. mysql> CREATE TRIGGER delete_file AFTER DELETE ON files FOR EACH ROW BEGIN
  42.     ->     DELETE FROM filedescriptions WHERE fileID = old.fileID;
  43.     ->   END;;
  44. Query OK, 0 rows affected (0.07 sec)

Haz las correcciones pertinentes y pruébalo en el servidor 5.0, y si, deberías considerar hacer la migración de tu BD, pero insisto que ante todo debes poner atención en lo que haces.

Saludos
Leo.
  #10 (permalink)  
Antiguo 22/03/2013, 09:17
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: bien planteado para manejar claves foraneas y FULLTEXT

Nota adicional a lo dicho por @leonardo_josue:
En la creación de rutinas (procedimientos, funciones, triggers, eventos), se usa DELIMITER para cambiar el comportamiento del intérprete de modo que tome la creación del objeto como un todo.
Eso está bien, pero lo que no debes hacer jamás es usar para nuevo delimitador caracteres que sean parte de los reservados para uso de MYSQL.
Nunca.
Estos son: !%&/()=^`´:;\|@#+-
Si observas con cuidado los ejemplos del manual verás que siempre usa "$$", porque ese par jamás se usa dentro del SQL.
No inventes cosas. Si se hace en el manual oficial de determinada forma es porque es conveniente hacerlo así de modo seguro.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #11 (permalink)  
Antiguo 22/03/2013, 13:31
 
Fecha de Ingreso: diciembre-2012
Mensajes: 21
Antigüedad: 11 años, 5 meses
Puntos: 0
Respuesta: bien planteado para manejar claves foraneas y FULLTEXT

Perdona leonardo_josue, me ha pasado eso que dices.

En mi tabla no tengo esos errores, pero quise recortarla porque no queria poner informacion basura que solo ocupara espacio. Se supone que despues del primary key hay un foreign Key. Y el "T NULL" es porque no borre bien lo que había en medio.

Tampoco tengo las comillas en mi tabla. Aunque confieso que no me di cuenta que las tenia hasta que las vi posteadas.


Definitivamente es seguro que no funciona en 5.0



De verdad que siento el despiste... En mi tabla estan bien.
Muchas gracias a los dos.

Etiquetas: claves, fulltext, manejar, tabla
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 11:11.