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

id´s autoincrementales

Estas en el tema de id´s autoincrementales en el foro de Mysql en Foros del Web. saludos a todos, debido a las especificaciones de mi proveedor de hosting estoy migrando a Mysql mi sistema web. En posgresql normalmente creaba los campos ...
  #1 (permalink)  
Antiguo 13/01/2014, 08:45
 
Fecha de Ingreso: julio-2012
Ubicación: bucaramanga
Mensajes: 19
Antigüedad: 11 años, 8 meses
Puntos: 1
Sonrisa id´s autoincrementales

saludos a todos,

debido a las especificaciones de mi proveedor de hosting estoy migrando a Mysql mi sistema web.
En posgresql normalmente creaba los campos id de cada tabla como seriales los cuales son autoincrementales y normalmente son llave primaria en su respectiva tabla sin embargo muchos de estos campos son llaves foraneas en otras tablas que además tienen otros id y al haber mas de un campo del tipo serial autoincremental en cualquier tabla echa en mysql me genera un error que especifica que no se puede tener mas de un tipo de datos serial en la tabla.

la pregunta es como puedo mantener esos campos autoincrementales, o me tocará por código php leer el valor del campo en la tabla y sumarle uno a la siguiente inserción para que se incrementen (cosa que me parece poco profesional)
En los ejemplos de bases de datos creadas en Mysql la mayoría de las veces veo que usan los id´s del tipo int ...pero me pregunto como harán para manejar el incremento.

gracias de antemano!
  #2 (permalink)  
Antiguo 13/01/2014, 08:58
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: id´s autoincrementales

En MySQL, por restricciones propias del DBMS no puede existir más de un AI en cada tabla, y normalmente sólo podría ser PK de la tabla o parte de ella.
Ahora bien, eso no impide que existan FK en la tabla A que referencien a la PK de una tabla B, que a su vez sea AI en la propia tabla B.
En ese sentido, da la impresión de que el AI que en PostgreSQL mencionas, fuese AI en una tabla donde es FK, cosa que no le encuentro mucho sentido, incluso si lo analizo como modelo de datos de una base relacional basada en el paradigma E-R.
Si el Ai es PK de la tabla B, no tiene por qué ser AI en la tabla A, ya que no pertenece a ella, sino a la B.
Siendo así, una de dos; o el modelo construido en PostgreSQL es incorrecto, o permite crear objetos que rompen con el paradigma relaciona... cosa que me parece poco probable.

¿Podrías explicar más claramente y ejemplificar lo que nos estas describiendo?
__________________
¿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 13/01/2014, 11:47
 
Fecha de Ingreso: julio-2012
Ubicación: bucaramanga
Mensajes: 19
Antigüedad: 11 años, 8 meses
Puntos: 1
Respuesta: id´s autoincrementales

entiendo lo que quieres decir, yo conserve el tipo de dato serial para los campos id precisamente por mantener la naturaleza del campo y no declarar un id serial en una tabla y luego declarar ese mismo campo con otro tipo de dato en otra tabla por eso pregunto como lo hacen en mysql cuando declaran una llave foranea en la tabla B que obviamente es llave primaria en otra tabla A y además es AI y además esa tabla B ya tiene una llave primaria AI.

especifico lo que hago en postgresql donde la tabla equipos define como llaves foraneas los campos idubica y idprotocolo los cuales son llaves primarias en sus respectivas tablas. ¿ cual es la manera correcta de hacerlo en mysql? ya que esto en porsgresql funciona correctamente y permite relacionar las tablas si generar redundancia el cual es el objetivo del modelo E-R
Código SQL:
Ver original
  1. CREATE TABLE ubicacion
  2. (
  3.   idubica serial NOT NULL,
  4.   descripcion CHARACTER(200),
  5.   CONSTRAINT idubica_pk PRIMARY KEY (idubica)
  6.  
  7. );
  8.  
  9. CREATE TABLE protocolos
  10. (
  11. idprotocolo serial,
  12. nombrequipo CHARACTER (100),
  13. descripcion CHARACTER (3000),
  14. CONSTRAINT idprotocolo_pk PRIMARY KEY (idprotocolo)
  15.  
  16. );
  17.  
  18.  
  19. CREATE TABLE equipos
  20. (
  21.   idprotocolo serial,
  22.   responsablemanten CHARACTER(100),
  23.   idequipo serial,
  24.   num_inv CHARACTER(100) NOT NULL,
  25.   nom_eq CHARACTER(100),
  26.   modelo CHARACTER(100),
  27.   marca CHARACTER(100),
  28.   num_serie CHARACTER(100),
  29.   estado CHARACTER(100),
  30.   garantia CHARACTER(30),
  31.   idubica serial,
  32.   clasificacion CHARACTER(100),
  33.   corriente CHARACTER(100),
  34.   voltaje CHARACTER(100),
  35.   frecuencia CHARACTER(100),
  36.   potencia CHARACTER(100),
  37.   invima CHARACTER(100),
  38.   funcion_equipo CHARACTER(500),
  39.   preventivo CHARACTER(50),
  40.   tipo CHARACTER(100),
  41.   imagen CHARACTER(100),
  42.   CONSTRAINT num_inv_pk PRIMARY KEY (num_inv),
  43.   CONSTRAINT idprotocolo_fk FOREIGN KEY (idprotocolo) REFERENCES protocolos,
  44.   CONSTRAINT idubica_fk FOREIGN KEY (idubica) REFERENCES ubicacion
  45.   ON UPDATE CASCADE ON DELETE CASCADE
  46. );

Última edición por gnzsoloyo; 13/01/2014 a las 13:00
  #4 (permalink)  
Antiguo 13/01/2014, 13:09
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: id´s autoincrementales

Bueno, viendo el breve script, hay algunas cosas que debes cambiar, si quieres usarlo en MySQL.
1) No existen los tipo de dato SERIAL. MySQL no los reconocerá. Este puede ser cambiado por MEDIUMITNT, INT o BIGINT, siempre UNSIGNED para evitar desperdicios, y porque no existen los SI negativos.
2) No existe el tipo de dato CHARACTER. Puede ser CHAR o VARCHAR.

En el contexto de tu script sería hacer esto:
Código MySQL:
Ver original
  1. CREATE TABLE ubicacion
  2. (
  3.   descripcion VARCHAR(200)
  4.  
  5. CREATE TABLE protocolos
  6. (
  7. nombrequipo VARCHAR(100),
  8. descripcion VARCHAR(3000)
  9.  
  10.  
  11. CREATE TABLE equipos
  12. (
  13.   idprotocolo INT UNSIGNED,
  14.   responsablemanten VARCHAR(100),
  15.   idequipo INT UNSIGNED,
  16.   num_inv VARCHAR(100) NOT NULL PRIMARY KEY, #Este tipo de dato no parece bien definido
  17.   nom_eq VARCHAR(100),
  18.   modelo VARCHAR(100),
  19.   marca VARCHAR(100),
  20.   num_serie VARCHAR(100),
  21.   estado VARCHAR(100),
  22.   garantia VARCHAR(30),
  23.   idubica INT UNSIGNED,
  24.   clasificacion VARCHAR(100),
  25.   corriente VARCHAR(100),
  26.   voltaje VARCHAR(100),         #Este tipo de dato no parece bien definido
  27.   frecuencia VARCHAR(100),    #Este tipo de dato no parece bien definido
  28.   potencia VARCHAR(100),       #Este tipo de dato no parece bien definido
  29.   invima VARCHAR(100),
  30.   funcion_equipo VARCHAR(500),
  31.   preventivo VARCHAR(50),
  32.   tipo VARCHAR(100),
  33.   imagen VARCHAR(100),
  34.   CONSTRAINT idprotocolo_fk FOREIGN KEY (idprotocolo) REFERENCES protocolos(idprotocolo)
  35.   CONSTRAINT idubica_fk FOREIGN KEY (idubica) REFERENCES ubicacion (idubica)

Más allá de esto, la tercera tabla no me parece ni normalizada ni bien depurada, ya que las longitudes de los campos parecen puestos al azar, y sin analizar sus características.
Por caso, corriente, voltaje y frecuencia, a mi me hablan de magnitudes, y por tanto entiendo que deberían ser valores numéricos y no de caracteres.
Y eso es un error conceptual que puede traer problemas severos a la hora de las consultas.

Por otro lado, existen aplicativos específicos para migrar bases de un DBMS a otro, que deberías aprovechar. Te evitaría hacer pasos innecesarios de pulido.
__________________
¿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 13/01/2014, 17:42
 
Fecha de Ingreso: julio-2012
Ubicación: bucaramanga
Mensajes: 19
Antigüedad: 11 años, 8 meses
Puntos: 1
Respuesta: id´s autoincrementales

antes que nada agradecer la ayuda y la pronta respuesta.

como ing. electrónico se bien el tipo de magnitudes que representan el voltaje, la corriente la potencia etc etc... sin embargo mi cliente no necesita hacer ninguna operación matemática con estos valores y además desea incluir en el dato ingresado el rango ya sea en mA, o A en el caso de la corriente o V o mV en el caso del voltaje la opcion clara: es varchar.

el dato num_inv hace referencia a un número de inventario que inicialmente consideré como entero pero al estar en campo trabajando en una institución te das cuenta que los números de inventario de los equipos muebles enceres etc etc no son precisamente números sino caracteres.

y por último las longitudes de los datos no son puestas al azar sinó mas bien un estimado del valor máximo que podrían tomar en casos extremos.

me tomo la molestia de especificar lo anterior ya que veo el interés en colaborar en todos los detalles, nuevamente agradezco la "traducción" del código a Mysql que me será muy util.
  #6 (permalink)  
Antiguo 13/01/2014, 18:21
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: id´s autoincrementales

Cita:
como ing. electrónico se bien el tipo de magnitudes que representan el voltaje, la corriente la potencia etc etc... sin embargo mi cliente no necesita hacer ninguna operación matemática con estos valores y además desea incluir en el dato ingresado el rango ya sea en mA, o A en el caso de la corriente o V o mV en el caso del voltaje la opcion clara: es varchar.
Bueno, perdona que discrepe, pero creo que eso es incorrecto. Antes de usar un VARCHAR, que resulta ineficiente, se usan dos campos, uno para definir la magnitud, y otro para indicar la unidad de medida.
Desde el punto de vista de un DBA, no tiene ningún sentido usar 100 bytes para almacenar una información que se puede almacenar con 10 (8 del valor y con toda la furia 2 para la unidad de representación).
Cita:
el dato num_inv hace referencia a un número de inventario que inicialmente consideré como entero pero al estar en campo trabajando en una institución te das cuenta que los números de inventario de los equipos muebles enceres etc etc no son precisamente números sino caracteres.
Eso es una decisión de diseño que puede salir del relevamiento. Si realmente lo usan así y siempre lo han usado como codificación alfanumérica, entonces si corresponde mantenerla.
Pero si la codificación alfanumerica responde a un conjunto de códigos alfabéticos, junto con un valor numérico, supongamos "AAABBCC000000", eso son cuatro campos al normalizarlo.
AL menos desde la óptica de BBDD, porque es mucho más eficiente tener los códigos separados y agrupados luego en la PK.
La performance de la base te lo agradecerá.
Cita:
y por último las longitudes de los datos no son puestas al azar sinó mas bien un estimado del valor máximo que podrían tomar en casos extremos.
OK. Entiendo.
De todos modos longitudes de datos con números enteros multiplos de 10, en BBDD implican redondeos por cota de alta, sin medir la longitud real.
Me refiero a que si un X dato se ha encontrado como máximo en 132 caracteres, ponerlo de 200 es redondear por exceso. Con 140 ó 150 alcanza. 200 son innecesarios y se pagan con costos de consulta.
La cosa, como decía mi profesor de Base de Datos I, es que la visión de ingenieros y programadores (sin desmerecer ninguna de las especialidades) es algo diferente a la forma en que el analista de datos ve los sistemas.
Cuando lo dijo creí que exageraba, pero diferentes experiencias me han confirmado su apreciación.
De allí que para mi la cosa se mire de un modo distinto, con detalles que parecen pequeñeces. Pero puedo asegurarte que cambios de ese tipo tienen un gran impacto a largo plazo.

Como sea, volviendo al problema central, ¿pudiste probar el script como te lo planteo?
Puede que aún haya que afinarlo, pero la cosa va por allí.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #7 (permalink)  
Antiguo 23/01/2014, 21:34
 
Fecha de Ingreso: julio-2012
Ubicación: bucaramanga
Mensajes: 19
Antigüedad: 11 años, 8 meses
Puntos: 1
Respuesta: id´s autoincrementales

bueno, el script funciona muy bien, de momento tengo un inconveniente con la tabla siguiente a la cual apliqué la misma sintaxis que en las anteriores sin embargo esta tabla cuyo nombre es 'baja' usa la llave foranea idubica que ya había sido declarada como llave foranea en la tabla anterior llamada equipos (esto en postgresql no tiene ningúna restricción sin embargo mysql si me arroja error).
Al eliminar el constraint donde declaraba como llave foranea idubica en esa nueva tabla 'baja' ahí si funcionó, sin embargo necesito saber como hago para que las demás tablas reconozcan ese campo idubica como llave foranea ya que lo uso en mas tablas:

coloco el código de la tabla siguiente al código anterior

CREATE TABLE baja
(
idbaja INT UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL,
fecha date,
idubica INT UNSIGNED,
num_inv VARCHAR(100),
observaciones VARCHAR(1000),
jefearea VARCHAR(100),
jefemto VARCHAR(100),
cooradmin VARCHAR(100),
CONSTRAINT idubica_fk FOREIGN KEY (idubica) REFERENCES ubicacion (idubica)
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT num_inv_fk FOREIGN KEY (num_inv) REFERENCES equipos (num_inv)
ON UPDATE CASCADE ON DELETE CASCADE
) Engine=INNODB;
  #8 (permalink)  
Antiguo 24/01/2014, 01:45
 
Fecha de Ingreso: julio-2012
Ubicación: bucaramanga
Mensajes: 19
Antigüedad: 11 años, 8 meses
Puntos: 1
Respuesta: id´s autoincrementales

bueno ya lo solucione simplemente eliminando el constraint idubica_fk y dejando el resto igual y lo mismo para constraint num_inv_fk
quedando esa ultima parte asi:

Código:
FOREIGN KEY (idubica) REFERENCES ubicacion (idubica) 
ON UPDATE CASCADE ON DELETE CASCADE,
FOREIGN KEY (num_inv) REFERENCES equipos (num_inv) 
ON UPDATE CASCADE ON DELETE CASCADE
  #9 (permalink)  
Antiguo 27/01/2014, 06:59
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: id´s autoincrementales

Eso con lo que te topaste, no aún error derivado de ser FK, sino que en MySQL las constraint deben tener nombres únicos por base, porque son los nombres de los índices que la administrar.
Con cambiarle la denominación al una de ellas alcanza.
Normalmente nosotros dejamos que el nombre de la constraint lo genere MySQL automáticamente.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)

Etiquetas: campo, php, sql, 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 07:48.