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

¿Se puede hacer esta consulta? Clave primaria PAR

Estas en el tema de ¿Se puede hacer esta consulta? Clave primaria PAR en el foro de Mysql en Foros del Web. Hola, Tengo una tabla con 5 columnas, Pero de esas 5, solo 2 son importantes para mi. Un id de usuario, y un id de ...
  #1 (permalink)  
Antiguo 18/12/2014, 06:50
 
Fecha de Ingreso: julio-2010
Mensajes: 134
Antigüedad: 13 años, 9 meses
Puntos: 0
¿Se puede hacer esta consulta? Clave primaria PAR

Hola,

Tengo una tabla con 5 columnas,
Pero de esas 5, solo 2 son importantes para mi. Un id de usuario, y un id de articulo.

El campo id usuario se puede repetir, y el campo id articulo tmb.
Pero lo que no puedo permitir es tener dos filas con el par(idusuario, idarticulo) repetido.

He probado poniendo las dos columnas claves primarias, y únicas pero evidentemente no funciona, solo me deja tener una fila con el mismo idusuario o e id articulo.

¿Cómo puedo solucionar esto?

Mi idea es que cuando vaya hacer un insert de una nueva fila, compruebe si ya existe el par(idusuario, idarticulo) insertado, y en caso afirmativo no hacerlo.

EDITO: una opción es hacer una consulta antes para comprobarlo, pero me parece poco eficiente.... ¿Hay alguna forma mejor?

Gracias
  #2 (permalink)  
Antiguo 18/12/2014, 07:08
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, 4 meses
Puntos: 2658
Respuesta: ¿Se puede hacer esta consulta? Clave primaria PAR

La clave primaria debe ser compuesta, eso hará que el par no se repita nunca.
Código MySQL:
Ver original
  1. CREATE TABLE usuario_articulo(
  2. usuario_id INT UNSIGNED NOT NULL,
  3. articulo_id INT UNSIGNED NOT NULL,
  4. ...
  5. PRIMARY KEY(usuario_id, articulo_id))
Es imposible en ese contexto que se repita un par (usuario_id, articulo_id).

Postea el create table de la tabla tal y como lo tienes ahora y veamos donde etá el error.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 18/12/2014, 08:43
 
Fecha de Ingreso: julio-2010
Mensajes: 134
Antigüedad: 13 años, 9 meses
Puntos: 0
Respuesta: ¿Se puede hacer esta consulta? Clave primaria PAR

Cita:
Iniciado por gnzsoloyo Ver Mensaje
La clave primaria debe ser compuesta, eso hará que el par no se repita nunca.
Código MySQL:
Ver original
  1. CREATE TABLE usuario_articulo(
  2. usuario_id INT UNSIGNED NOT NULL,
  3. articulo_id INT UNSIGNED NOT NULL,
  4. ...
  5. PRIMARY KEY(usuario_id, articulo_id))
Es imposible en ese contexto que se repita un par (usuario_id, articulo_id).

Postea el create table de la tabla tal y como lo tienes ahora y veamos donde etá el error.
Mmmm, ahora mismo lo tengo asi para que me funcione.

Código MySQL:
Ver original
  1. CREATE TABLE IF NOT EXISTS `j25_push_comentarios_grupos` (
  2.   `user_id` int(11) NOT NULL DEFAULT '0',
  3.   `user_id_nacional` int(11) NOT NULL,
  4.   `type` varchar(255) NOT NULL DEFAULT '',
  5.   `item` varchar(255) NOT NULL DEFAULT '',
  6.   `params` text,
  7.   PRIMARY KEY (`id`),
  8.   KEY `user_id` (`user_id`),
  9.   KEY `type` (`type`),
  10.   KEY `item` (`item`)
  11. ) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3144 ;

Pero no recuerdo haber probado como lo has puesto tu.... lo hice de otra forma.
Exactamente como lo hago?

Quito PRIMARY KEY (`id`),
y lo sustituyo por:
PRIMARY KEY(`user_id`, `item`) ??
  #4 (permalink)  
Antiguo 18/12/2014, 08: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, 4 meses
Puntos: 2658
Respuesta: ¿Se puede hacer esta consulta? Clave primaria PAR

Ese "ID" autoincremental es innecesario, y sóilo te geenerará problemas. Quítalo.
Código MySQL:
Ver original
  1. CREATE TABLE IF NOT EXISTS `j25_push_comentarios_grupos` (
  2.   `user_id` int(11) NOT NULL,
  3.   `user_id_nacional` int(11) NOT NULL,
  4.   `type` varchar(255) NOT NULL DEFAULT '',
  5.   `item` varchar(255) NOT NULL DEFAULT '',
  6.   `params` text,
  7.   PRIMARY KEY (`user_id`, `type`)
  8. ) ENGINE=MyISAM  DEFAULT CHARSET=latin1;

Por otro lado:
- ¿Para qué ese campo "params"? Espero que no sean parámetros o valores separado spor comas....
- Los VARCHAR ya no tienen limite de 255 caracteres, ¿lo sabías?
- "item" ¿qué tpo de datos almacena?
- Nunca pongas un valor por default a un campo clave. Es un erro grave.
__________________
¿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 18/12/2014, 09:20
 
Fecha de Ingreso: julio-2010
Mensajes: 134
Antigüedad: 13 años, 9 meses
Puntos: 0
Respuesta: ¿Se puede hacer esta consulta? Clave primaria PAR

Cita:
Iniciado por gnzsoloyo Ver Mensaje
Ese "ID" autoincremental es innecesario, y sóilo te geenerará problemas. Quítalo.
Código MySQL:
Ver original
  1. CREATE TABLE IF NOT EXISTS `j25_push_comentarios_grupos` (
  2.   `user_id` int(11) NOT NULL,
  3.   `user_id_nacional` int(11) NOT NULL,
  4.   `type` varchar(255) NOT NULL DEFAULT '',
  5.   `item` varchar(255) NOT NULL DEFAULT '',
  6.   `params` text,
  7.   PRIMARY KEY (`user_id`, `type`)
  8. ) ENGINE=MyISAM  DEFAULT CHARSET=latin1;

Por otro lado:
- ¿Para qué ese campo "params"? Espero que no sean parámetros o valores separado spor comas....
- Los VARCHAR ya no tienen limite de 255 caracteres, ¿lo sabías?
- "item" ¿qué tpo de datos almacena?
- Nunca pongas un valor por default a un campo clave. Es un erro grave.

Je...... oooki.
La verdad es que en cuanto a contruccion de tablas en SQL soy demasiado novato, pero esa tabla no la he hecho yo exactamente.

Esa tabla es de un componente de Joomla.

El autoincremente ya venia así, ¿que problemas me puede traer?

Y si, ese campo params es una cadena de texto y esta separado por comas, cada uno es un "parámetro" se podría decir.... la mitad de las tablas que tiene Joomla son asi.... Desde la ignorancia... ¿Cuál es el problema?

Lo de los VARCHAR, lo mismo, es de joomla. Pero no, no sabia que ya no tenían limite.

Ítem almacena un entero, un numero.

-Puedes explicarme el por que no poner un valor por default en un campo clave?

Mil gracias
  #6 (permalink)  
Antiguo 20/12/2014, 05:27
 
Fecha de Ingreso: julio-2010
Mensajes: 134
Antigüedad: 13 años, 9 meses
Puntos: 0
Respuesta: ¿Se puede hacer esta consulta? Clave primaria PAR

ei, lo subo, que me he quedado con toda la curiosidad de en que me puedo estar equivocando!
  #7 (permalink)  
Antiguo 20/12/2014, 08:06
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, 4 meses
Puntos: 2658
Respuesta: ¿Se puede hacer esta consulta? Clave primaria PAR

Las explicaciones son varias, y algunas en realidad son algo largas...
Cita:
Esa tabla es de un componente de Joomla.
Joomla, como herramienta, es una aplciación multipropósito, que no respeta fielmente el modelo Entidad-relación, en aras de dar flexibilidad a las construcciones. Pero cuando agregas algo, debes tratar de atenerte a diseños correctos. De lo contrario estarás agregando ineficiencia y atentando contra la performance.

Cita:
El autoincremente ya venia así, ¿que problemas me puede traer?
El autoincremental es innecesario porque la PK definida como compuesta, ya genera lo que s una PK, y ese auntoincremental pierde sentido. Los auutoincrementales se usan por simplicidad para programar, pero no son necesarios en una BDD salvo para determinados usos. Una PK no necesita ser ni numérica ni incremental, sino identificar univocamente cada registro de la tabla, y con esos dos campos componiendo la PK es más que suficiente.

Cita:
Y si, ese campo params es una cadena de texto y esta separado por comas, cada uno es un "parámetro" se podría decir.... la mitad de las tablas que tiene Joomla son asi.... Desde la ignorancia... ¿Cuál es el problema?
Una de las estrictas prohibiciones del modelo E-R es que no deben existir campos multivaluados, bajo ninguna circunstancia. La existencia de campos multivaluados muestra que es una base desnormalizada (viola la 1FN).
Ese tipo de campos son usados en herramientas como Joomla y otros, porque se basan en taxonomías, y no en relaciones, las relaciones se construyen en ese caso programáticamente, lo que hace que la base se transforme en una bolsa de bolsas de datos, con alto riesgo de inconsistencia.
El problema a corto plazo es que como esos campos tienen múltiples valores, no sirven para relacionar estructuralmente las entidades, no son adecuados para consultas eficientes y optimizadas, y tienden a generar gran cantidad de redundancia.
Escribir consultas sobre campos multivaluados lleva, entre otras cosas, a usar funciones de cadena en MYSQL para poder lograr los resultados. El uso de excesivas funciones tarde o temprano conspira contra la performance.
Además, puede obligar a leer datos desde la aplicación, procesarlos en la aplicación, enviar nuevas consultas con esos datos, recuperar otro bloque a procesar y volver a inciar el ciclo, antes de obtener lo que realmente se deseaba. Todo es vaivén de idas y vueltas entre la aplicación y la base implica dos cosas: 1) exceso de acoplamiento entre aplicación y base (un defecto de software grave), y 2) Exceso de transacciones a la base, que conlleva costos operativos y de proceso.
En síntesis: en la práctica es una mala idea... y en diseño de datos, un campo multivaluado es suficiente para reprobar cualquier examen sin que el profesor siga leyendo lo que se escribió.


Cita:
Lo de los VARCHAR, lo mismo, es de joomla. Pero no, no sabia que ya no tenían limite.
Todo tipo de columna tiene límite. Lo que decía es que el límite del VARCHAR no es 255, sino 65535, como dice el manual.

Cita:
Ítem almacena un entero, un numero.
Si "item" guarda un número, corresponde que uses columnas numéricas, no de cadena. Los números no se almacenan como cifras, sino como binarios, lo que significa que para almacenar un valor entre -128 y +127 , o bien entre 0 y 255 se usa 1 byte (8 bits de ancho), y no 4 bytes como cadena. Y para almacenar un numero como 18446744073709551615 se usan 8 bytes, en lugar de 20...

Cita:
-Puedes explicarme el por que no poner un valor por default en un campo clave?
Un campo que es PK no puede tener valor por default por la simple razón de que es PK: Sus valores son únicos en la tabla, y si pusieses un valor por default, si no ingresas los valores correspondiente se podría generar un valor PK ya existente, lo que dispararía un error de inserción por clave duplicada.
Además, uno de los principios de las PK es que son datos obligatorios, por lo que jamás puedes dejarlos nulos, ni intentar poner un nulo.
¿Se entiende?

Ergo, si los campos son PK, no deben tener valores por default.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)

Última edición por gnzsoloyo; 20/12/2014 a las 08:12

Etiquetas: campo, clave, par, primaria, 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 22:57.