FAQ
Hola lista!!!

me gustaría saber, que pensáis de averiguar el id de un registro utilizando
instrucciones tipo: *

mysql_insert_id($link); * ( devuelve el último id introducido )

Por ejemplo realizamos un insert

$sql = "insert into ... "
if(mysql_query($sql,$link) )
{
$id = mysql_insert_id($link)
}

en una aplicación multi-usuario, sería fiable ¿? , alguién tiene experiencia
con este tipo de casos ¿?

claro está que he intentado simplificar mucho el ejemplo anterior,
actualmente, uso PDO.

Pido vuestra opinión, porque pese a llevar muchos años programando en PHP,
casi nunca he implementado estructuras de ese tipo, la razón desconfianza.

Un saludo!!!


--
Ricardo
_______________________________________________
IT Architect
website: http://www.pulsarinara.com

Search Discussions

  • Juan Manuel Acuña Barrera at Jun 23, 2011 at 9:09 pm

    El 23/06/2011, a las 13:28, Ricardo Martinez escribió:

    Hola lista!!!

    me gustaría saber, que pensáis de averiguar el id de un registro utilizando
    instrucciones tipo: *

    mysql_insert_id($link); * ( devuelve el último id introducido )

    Por ejemplo realizamos un insert

    $sql = "insert into ... "
    if(mysql_query($sql,$link) )
    {
    $id = mysql_insert_id($link)
    }

    en una aplicación multi-usuario, sería fiable ¿? , alguién tiene experiencia
    con este tipo de casos ¿?

    claro está que he intentado simplificar mucho el ejemplo anterior,
    actualmente, uso PDO.

    Pido vuestra opinión, porque pese a llevar muchos años programando en PHP,
    casi nunca he implementado estructuras de ese tipo, la razón desconfianza.

    Un saludo!!!


    --
    Ricardo
    _______________________________________________
    IT Architect
    website: http://www.pulsarinara.com
    Hola, lo que preguntas se llama "condición de carrera", por lo de tener muchos usuarios simultáneamente. En mi humilde experiencia, esto se puede dar por dos situaciones: la primera, que tengas _realmente_ muchos usuarios y/o consultas simultáneas; y la segunda, cuando por alguna razón hay problemas de conexión entre tu aplicación y el mysql y entren "de golpe" muchas consultas/inserts.

    Asumiendo que el "id" del que estás hablando es un auto-increment, en mi experiencia la solución que yo he aplicado y me ha funcionado bastante bien es:

    1.- Crear un número pseudo-aleatorio grande (8 a 10 cifras).
    2.- Incluirlo en el insert (se debe tener un campo preparado para esto (entero, not-null):
    $sql = "insert into tabla values ('$valor1','$valor2',......,'$valorN','$numeroAleatorio') ";
    3.- Recuperar el id, usando una consulta con los valores insertados:
    $sql = "select id from tabla where (valor1='$valor1' AND valor2='$valor2' AND ..... valorN='$valorN' AND numeroAleatorio='$numeroAleatorio') order by id desc limit 1";

    A reserva de lo que opinen otros compañeros de la lista, esta solución, aunque no es la más eficiente, si es una que me ha dado muy buenos resultados en materia de fiabilidad, al grado que te puedo decir que de muchos millones de inserts, nunca he tenido un problema en este sentido.

    Quedo a la espera de sus comentarios.

    Juan Manuel Acuña




    PD me encanta la idea de "jueves de debate" :)
  • Federica Pavese at Jun 23, 2011 at 9:29 pm
    Hola a todos !
    Ricardo: para qué necesitás el id del registro?
    De esto también depende la respuesta que podamos darte.
    Porque por ejemplo: si lo necesitás para después introducirlo en otras
    tablas y relacionar todas las tablas por el id... entonces podés usar
    transacciones (begin-commit-rollback).
    Hasta que no se ejecuta el commit (o el rollback), no entra otra transacción
    y el valor del id se mantiene.

    Federica






    ----- Original Message -----
    From: "Juan Manuel Acuña Barrera" <[email protected]>
    To: "Lista PHP en español" <[email protected]>
    Cc: "Ricardo Martinez" <[email protected]>
    Sent: Thursday, June 23, 2011 6:08 PM
    Subject: Re: [PHP-ES] alguien ha usado ... o se fía de ... ( jueves de
    debate ;)


    -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1


    El 23/06/2011, a las 13:28, Ricardo Martinez escribió:
    Hola lista!!!

    me gustaría saber, que pensáis de averiguar el id de un registro
    utilizando
    instrucciones tipo: *

    mysql_insert_id($link); * ( devuelve el último id introducido )

    Por ejemplo realizamos un insert

    $sql = "insert into ... "
    if(mysql_query($sql,$link) )
    {
    $id = mysql_insert_id($link)
    }

    en una aplicación multi-usuario, sería fiable ¿? , alguién tiene
    experiencia
    con este tipo de casos ¿?

    claro está que he intentado simplificar mucho el ejemplo anterior,
    actualmente, uso PDO.

    Pido vuestra opinión, porque pese a llevar muchos años programando en PHP,
    casi nunca he implementado estructuras de ese tipo, la razón desconfianza.

    Un saludo!!!


    --
    Ricardo
    _______________________________________________
    IT Architect
    website: http://www.pulsarinara.com
    Hola, lo que preguntas se llama "condición de carrera", por lo de tener
    muchos usuarios simultáneamente. En mi humilde experiencia, esto se puede
    dar por dos situaciones: la primera, que tengas _realmente_ muchos usuarios
    y/o consultas simultáneas; y la segunda, cuando por alguna razón hay
    problemas de conexión entre tu aplicación y el mysql y entren "de golpe"
    muchas consultas/inserts.

    Asumiendo que el "id" del que estás hablando es un auto-increment, en mi
    experiencia la solución que yo he aplicado y me ha funcionado bastante bien
    es:

    1.- Crear un número pseudo-aleatorio grande (8 a 10 cifras).
    2.- Incluirlo en el insert (se debe tener un campo preparado para esto
    (entero, not-null):
    $sql = "insert into tabla values
    ('$valor1','$valor2',......,'$valorN','$numeroAleatorio') ";
    3.- Recuperar el id, usando una consulta con los valores insertados:
    $sql = "select id from tabla where (valor1='$valor1' AND valor2='$valor2'
    AND ..... valorN='$valorN' AND numeroAleatorio='$numeroAleatorio') order by
    id desc limit 1";

    A reserva de lo que opinen otros compañeros de la lista, esta solución,
    aunque no es la más eficiente, si es una que me ha dado muy buenos
    resultados en materia de fiabilidad, al grado que te puedo decir que de
    muchos millones de inserts, nunca he tenido un problema en este sentido.

    Quedo a la espera de sus comentarios.

    Juan Manuel Acuña




    PD me encanta la idea de "jueves de debate" :)





    --
    PHP Spanish Localization Talk Mailing List (http://www.php.net/)
    To unsubscribe, visit: http://www.php.net/unsub.php



    __________ Información de ESET NOD32 Antivirus, versión de la base de firmas
    de virus 6232 (20110623) __________

    ESET NOD32 Antivirus ha comprobado este mensaje.

    http://www.eset.com




    __________ Información de ESET NOD32 Antivirus, versión de la base de firmas de virus 6232 (20110623) __________

    ESET NOD32 Antivirus ha comprobado este mensaje.

    http://www.eset.com
  • @ndrés at Jun 23, 2011 at 11:04 pm
    2011/6/23 Federica Pavese <[email protected]>
    Hola a todos !
    Ricardo: para qué necesitás el id del registro?
    De esto también depende la respuesta que podamos darte.
    Porque por ejemplo: si lo necesitás para después introducirlo en otras
    tablas y relacionar todas las tablas por el id... entonces podés usar
    transacciones (begin-commit-rollback).
    Hasta que no se ejecuta el commit (o el rollback), no entra otra
    transacción y el valor del id se mantiene.

    Federica

    Apoyando la idea de Federica, lo mejor sería crear un stored procedure que
    devuelva el valor insertado en caso de éxito
  • Ricardo Martinez at Jun 24, 2011 at 8:45 am
    hola a todos!

    lo primero de todo, gracias por responder, he estado mirando las diferentes
    soluciones que cada uno aportado así como experiencia en casos anteriores.

    voy en orden como habéis escrito:

    *Carlos Costa: *
    te refieres a crear una tabla auxiliar, con un id auto increment, de forma,
    que cada vez que queramos generar un registro en la tabla principal, el
    campo id se obtenga de la tabla aux. Corrígeme si me equivoco, pero el
    problema que veo es que podemos llegar a tener muchos ids en la tabla
    auxiliar que no se usen( dependiendo del diseño y necesidades de la
    aplicación).
    Y no soluciona el problema de multi-usuario(al menos en mi caso, que explico
    más abajo).
    De todas formas, igual no te he comprendido bien. Pero es bueno idea
    también.

    *Juan Manuel:*
    efectivamente es un id autoincrement, tu solución me parece, que puede
    llegar a ser muy útil, como control.

    *Federica:*
    Tengo dos tablas, tabla principal y tabla secundaria.
    El usuario realiza una determinada acción y en ese momento, se crear un
    registro en la tabla principal, y la vez se le da opción de insertar otro
    registro en la tabla secundaria, estas dos tablas van relacionadas por el id
    de la tabla principal, que es autoincrement.

    Voy a revisar documentación y a probar esto, pero veo que se genera más
    código.

    ...

    He estado preguntando el tema con otros colegas (*mysql_insert_id($link);*),
    que han desarrollado aplicaciones con muchos usuarios online a la vez, y me
    han comentado, *que se obtiene la última transacción a la base de datos que
    tienes tu abierta*.

    Así que voy a probar con los stored procedures y con mysql_insert_id en su
    versión para PDO. ya os comentaré los resultados!!!

    pd gracias a [email protected], y si os parece cada jueves podría haber algún pequeño
    tema a debate!!!



    --
    Ricardo
    _______________________________________________
    IT Architect
    website: http://www.pulsarinara.com
  • Juan Manuel Acuña Barrera at Jun 24, 2011 at 2:36 pm

    El 24/06/2011, a las 03:45, Ricardo Martinez escribió:

    hola a todos!

    lo primero de todo, gracias por responder, he estado mirando las diferentes
    soluciones que cada uno aportado así como experiencia en casos anteriores.

    voy en orden como habéis escrito:

    *Carlos Costa: *
    te refieres a crear una tabla auxiliar, con un id auto increment, de forma,
    que cada vez que queramos generar un registro en la tabla principal, el
    campo id se obtenga de la tabla aux. Corrígeme si me equivoco, pero el
    problema que veo es que podemos llegar a tener muchos ids en la tabla
    auxiliar que no se usen( dependiendo del diseño y necesidades de la
    aplicación).
    Y no soluciona el problema de multi-usuario(al menos en mi caso, que explico
    más abajo).
    De todas formas, igual no te he comprendido bien. Pero es bueno idea
    también.

    *Juan Manuel:*
    efectivamente es un id autoincrement, tu solución me parece, que puede
    llegar a ser muy útil, como control.

    *Federica:*
    Tengo dos tablas, tabla principal y tabla secundaria.
    El usuario realiza una determinada acción y en ese momento, se crear un
    registro en la tabla principal, y la vez se le da opción de insertar otro
    registro en la tabla secundaria, estas dos tablas van relacionadas por el id
    de la tabla principal, que es autoincrement.

    Voy a revisar documentación y a probar esto, pero veo que se genera más
    código.

    ...

    He estado preguntando el tema con otros colegas (*mysql_insert_id($link);*),
    que han desarrollado aplicaciones con muchos usuarios online a la vez, y me
    han comentado, *que se obtiene la última transacción a la base de datos que
    tienes tu abierta*.

    Así que voy a probar con los stored procedures y con mysql_insert_id en su
    versión para PDO. ya os comentaré los resultados!!!

    pd gracias a [email protected], y si os parece cada jueves podría haber algún pequeño
    tema a debate!!!



    --
    Ricardo
    _______________________________________________
    IT Architect
    website: http://www.pulsarinara.com
    Hola.

    Olvidé mencionar que a mi me gusta particularmente el método que uso ya que no me gusta mostrar mas información al usuario de la estrictamente necesaria, especialmente en los vínculos.

    En alguna ocasión, para rizar más el rizo, en lugar de usar una cadena numérica aleatoria, usé un hash único. Te pongo el código para crearlo abajo:

    $seed='lkSldPeIXuzMshYgYTnkkiyQsC';
    $hash=sha1(uniqid($seed . mt_rand(), true));
    echo "seed: $seed <br>";
    echo "hash: $hash <br>";

    Y si quieres que tu cadena no sea tan larga, por ejemplo, para que te quede de 10 caracteres:

    $random=rand(0,15);
    $short=substr($hash,$random,10);
    echo "short: $short <br>";

    La idea es no poner nada que sea predecible. No es lo mismo que un vínculo apunte a "pagina.php?id=132549", donde, sin mucho cerebro un usuario se le podría ocurrir cambiar el número a ver si accede a otros datos, que un vínculo que apunte a "pagina.php?acceso= 4b59604b9c36c6bd78255d75e4c029a14f94f0b8".

    Más de uno me tachará de paranóico, desconfiado y similares... y tendrá razón :)

    Espero que te sirva.

    Saludos!
    Juan Manuel Acuña.
  • Ivan Rico at Jun 23, 2011 at 10:40 pm
    yo siempre utilice esa función para obtener el último id y nunca tuve problemas,

    la razón de esta confiabilidad consiste en que cuando ejecutas la transacción el id generado se mantiene disponible solo para la conexión que hiciste, osea el mysql_connect() que estas usando, si hay muchos insert al mismo tiempo de diferentes clientes a cada sesión le devolvera solo el id que se generó cada quién, por la simple y sencilla razón de que cada ejecución lanzo su propio mysql_connect()


    espero haber sido sido claro.

    por cierto ahora que utilizo los stored procedures uso la función de mysql que se llama LAST_INSERT_ID()

    saludos



    ----- Mensaje original -----
    De: "Federica Pavese" <[email protected]>
    Para: "Lista PHP en español" <[email protected]>
    Enviados: Jueves, 23 de Junio 2011 16:28:49 GMT -06:00 Guadalajara / Ciudad de México / Monterrey
    Asunto: Re: [PHP-ES] alguien ha usado ... o se fía de ... ( jueves de debate ;)

    Hola a todos !
    Ricardo: para qué necesitás el id del registro?
    De esto también depende la respuesta que podamos darte.
    Porque por ejemplo: si lo necesitás para después introducirlo en otras
    tablas y relacionar todas las tablas por el id... entonces podés usar
    transacciones (begin-commit-rollback).
    Hasta que no se ejecuta el commit (o el rollback), no entra otra transacción
    y el valor del id se mantiene.

    Federica






    ----- Original Message -----
    From: "Juan Manuel Acuña Barrera" <[email protected]>
    To: "Lista PHP en español" <[email protected]>
    Cc: "Ricardo Martinez" <[email protected]>
    Sent: Thursday, June 23, 2011 6:08 PM
    Subject: Re: [PHP-ES] alguien ha usado ... o se fía de ... ( jueves de
    debate ;)


    -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1


    El 23/06/2011, a las 13:28, Ricardo Martinez escribió:
    Hola lista!!!

    me gustaría saber, que pensáis de averiguar el id de un registro
    utilizando
    instrucciones tipo: *

    mysql_insert_id($link); * ( devuelve el último id introducido )

    Por ejemplo realizamos un insert

    $sql = "insert into ... "
    if(mysql_query($sql,$link) )
    {
    $id = mysql_insert_id($link)
    }

    en una aplicación multi-usuario, sería fiable ¿? , alguién tiene
    experiencia
    con este tipo de casos ¿?

    claro está que he intentado simplificar mucho el ejemplo anterior,
    actualmente, uso PDO.

    Pido vuestra opinión, porque pese a llevar muchos años programando en PHP,
    casi nunca he implementado estructuras de ese tipo, la razón desconfianza.

    Un saludo!!!


    --
    Ricardo
    _______________________________________________
    IT Architect
    website: http://www.pulsarinara.com
    Hola, lo que preguntas se llama "condición de carrera", por lo de tener
    muchos usuarios simultáneamente. En mi humilde experiencia, esto se puede
    dar por dos situaciones: la primera, que tengas _realmente_ muchos usuarios
    y/o consultas simultáneas; y la segunda, cuando por alguna razón hay
    problemas de conexión entre tu aplicación y el mysql y entren "de golpe"
    muchas consultas/inserts.

    Asumiendo que el "id" del que estás hablando es un auto-increment, en mi
    experiencia la solución que yo he aplicado y me ha funcionado bastante bien
    es:

    1.- Crear un número pseudo-aleatorio grande (8 a 10 cifras).
    2.- Incluirlo en el insert (se debe tener un campo preparado para esto
    (entero, not-null):
    $sql = "insert into tabla values
    ('$valor1','$valor2',......,'$valorN','$numeroAleatorio') ";
    3.- Recuperar el id, usando una consulta con los valores insertados:
    $sql = "select id from tabla where (valor1='$valor1' AND valor2='$valor2'
    AND ..... valorN='$valorN' AND numeroAleatorio='$numeroAleatorio') order by
    id desc limit 1";

    A reserva de lo que opinen otros compañeros de la lista, esta solución,
    aunque no es la más eficiente, si es una que me ha dado muy buenos
    resultados en materia de fiabilidad, al grado que te puedo decir que de
    muchos millones de inserts, nunca he tenido un problema en este sentido.

    Quedo a la espera de sus comentarios.

    Juan Manuel Acuña




    PD me encanta la idea de "jueves de debate" :)





    --
    PHP Spanish Localization Talk Mailing List (http://www.php.net/)
    To unsubscribe, visit: http://www.php.net/unsub.php



    __________ Información de ESET NOD32 Antivirus, versión de la base de firmas
    de virus 6232 (20110623) __________

    ESET NOD32 Antivirus ha comprobado este mensaje.

    http://www.eset.com




    __________ Información de ESET NOD32 Antivirus, versión de la base de firmas de virus 6232 (20110623) __________

    ESET NOD32 Antivirus ha comprobado este mensaje.

    http://www.eset.com




    --
    PHP Spanish Localization Talk Mailing List (http://www.php.net/)
    To unsubscribe, visit: http://www.php.net/unsub.php
  • David Blanco at Jun 24, 2011 at 1:06 pm
    Hola!

    El 23 de junio de 2011 20:28, Ricardo Martinez <[email protected]>escribió:

    me gustaría saber, que pensáis de averiguar el id de un registro utilizando
    instrucciones tipo: *

    mysql_insert_id($link); * ( devuelve el último id introducido )

    en una aplicación multi-usuario, sería fiable ¿? , alguién tiene
    experiencia
    con este tipo de casos ¿?
    Yo en tiempos usaba secuencias. Creo que MySQL no las soporta pero adoDB,
    que era la librería que usábamos, las simulaba con una tabla auxiliar donde
    sólo almacenaba el valor del último ID utilizado por lo que no había
    problemas de concurrencia. Generabas un nuevo ID incrementando el valor del
    campo de la tabla auxiliar y listo.

    En cualquier caso, la opción de las transacciones creo que es muy
    recomendable.


    Un saludo
  • Satyam at Jun 24, 2011 at 3:07 pm
    Creo que se están enrollando demasiado con este asunto, buscando
    soluciones que consumen recursos innecesarios y/o no son 100% seguras.

    mysql_insert_id es seguro. El motor SQL hace la inserción del registro y la verificación del ID asignado dentro de una transacción
    por lo que no es posible que otro usuario hiciera nada entre ambas operaciones. El motor guarda el ID generado dentro de los
    datos asociados a la conexion abierta por lo que tampoco puede confundirse con el de otras conexiones.

    Aquellos motores (no me consta que exista alguno) que no pudieran soportar esta funcionalidad simplemente no proveeran una funcion de este tipo.
    Seria ilogico que un motor proveyera un id autoincremental y que no previera los mecanismos para obtener ese valor de forma confiable,
    máxime si pensamos que dicho ID es la principal forma de recuperar esta información. Sería absurdo que, después de tantos años,
    nosotros fueramos a descubrir que en realidad no es confiable!

    El manual de MySql explicitamente dice que LAST_INSERT_ID (la function de SQL invocada por mysql_insert_id) es segura:
    http://dev.mysql.com/doc/refman/5.6/en/information-functions.html#function_last-insert-id

    Satyam




    El 24/06/2011 11:26, David Blanco escribió:
    Hola!

    El 23 de junio de 2011 20:28, Ricardo Martinez<[email protected]>escribió:

    me gustaría saber, que pensáis de averiguar el id de un registro utilizando
    instrucciones tipo: *

    mysql_insert_id($link); * ( devuelve el último id introducido )

    en una aplicación multi-usuario, sería fiable ¿? , alguién tiene
    experiencia
    con este tipo de casos ¿?
    Yo en tiempos usaba secuencias. Creo que MySQL no las soporta pero adoDB,
    que era la librería que usábamos, las simulaba con una tabla auxiliar donde
    sólo almacenaba el valor del último ID utilizado por lo que no había
    problemas de concurrencia. Generabas un nuevo ID incrementando el valor del
    campo de la tabla auxiliar y listo.

    En cualquier caso, la opción de las transacciones creo que es muy
    recomendable.


    Un saludo



    -----
    No virus found in this message.
    Checked by AVG - www.avg.com
    Version: 10.0.1388 / Virus Database: 1513/3722 - Release Date: 06/23/11
  • Ivan Rico at Jun 24, 2011 at 3:52 pm
    totalmente de acuerdo y eso fué lo que puse en mi mensaje anterior

    en resumen si quieren hacer las cosas eficaces y eficientes utilicen mysql_insert_id() cualquier otra solución seguramente pegara en desempeño y seguridad de forma negativa


    saludos


    ----- Mensaje original -----
    De: "Satyam" <[email protected]>
    Para: [email protected]
    Enviados: Viernes, 24 de Junio 2011 8:42:48 GMT -06:00 Guadalajara / Ciudad de México / Monterrey
    Asunto: Re: [PHP-ES] alguien ha usado ... o se fía de ... ( jueves de debate ;)

    Creo que se están enrollando demasiado con este asunto, buscando
    soluciones que consumen recursos innecesarios y/o no son 100% seguras.

    mysql_insert_id es seguro. El motor SQL hace la inserción del registro y la verificación del ID asignado dentro de una transacción
    por lo que no es posible que otro usuario hiciera nada entre ambas operaciones. El motor guarda el ID generado dentro de los
    datos asociados a la conexion abierta por lo que tampoco puede confundirse con el de otras conexiones.

    Aquellos motores (no me consta que exista alguno) que no pudieran soportar esta funcionalidad simplemente no proveeran una funcion de este tipo.
    Seria ilogico que un motor proveyera un id autoincremental y que no previera los mecanismos para obtener ese valor de forma confiable,
    máxime si pensamos que dicho ID es la principal forma de recuperar esta información. Sería absurdo que, después de tantos años,
    nosotros fueramos a descubrir que en realidad no es confiable!

    El manual de MySql explicitamente dice que LAST_INSERT_ID (la function de SQL invocada por mysql_insert_id) es segura:
    http://dev.mysql.com/doc/refman/5.6/en/information-functions.html#function_last-insert-id

    Satyam




    El 24/06/2011 11:26, David Blanco escribió:
    Hola!

    El 23 de junio de 2011 20:28, Ricardo Martinez<[email protected]>escribió:

    me gustaría saber, que pensáis de averiguar el id de un registro utilizando
    instrucciones tipo: *

    mysql_insert_id($link); * ( devuelve el último id introducido )

    en una aplicación multi-usuario, sería fiable ¿? , alguién tiene
    experiencia
    con este tipo de casos ¿?
    Yo en tiempos usaba secuencias. Creo que MySQL no las soporta pero adoDB,
    que era la librería que usábamos, las simulaba con una tabla auxiliar donde
    sólo almacenaba el valor del último ID utilizado por lo que no había
    problemas de concurrencia. Generabas un nuevo ID incrementando el valor del
    campo de la tabla auxiliar y listo.

    En cualquier caso, la opción de las transacciones creo que es muy
    recomendable.


    Un saludo



    -----
    No virus found in this message.
    Checked by AVG - www.avg.com
    Version: 10.0.1388 / Virus Database: 1513/3722 - Release Date: 06/23/11
    --
    PHP Spanish Localization Talk Mailing List (http://www.php.net/)
    To unsubscribe, visit: http://www.php.net/unsub.php

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupphp-general-es @
categoriesphp
postedJun 23, '11 at 6:28p
activeJun 24, '11 at 3:52p
posts10
users7
websitephp.net

People

Translate

site design / logo © 2023 Grokbase