Saltar al contenido

MySQL Insertar en varias tablas? (¿Normalización de la base de datos?)

Después de tanto trabajar hemos hallado la contestación de esta contratiempo que tantos usuarios de nuestra web tienen. Si tienes alguna información que compartir no dejes de compartir tu información.

Solución:

No, no puede insertar en varias tablas en un comando MySQL. Sin embargo, puede utilizar transacciones.

BEGIN;
INSERT INTO users (username, password)
  VALUES('test', 'test');
INSERT INTO profiles (userid, bio, homepage) 
  VALUES(LAST_INSERT_ID(),'Hello world!', 'http://www.stackoverflow.com');
COMMIT;

Mira esto LAST_INSERT_ID() para reutilizar los valores de incremento automático.

Edito: dijiste “Después de todo este tiempo tratando de resolverlo, todavía no funciona. ¿No puedo simplemente poner el ID recién generado en $var y poner ese $var en todos los comandos de MySQL?

Permítanme elaborar: hay 3 formas posibles aquí:

  1. En el código que ves arriba. Esto lo hace todo en MySQL, y el
    LAST_INSERT_ID() en la segunda declaración será automáticamente el valor de la columna de autoincremento que se insertó en la primera declaración.

    Desafortunadamente, cuando la segunda declaración inserta filas en una tabla con una columna de incremento automático, la LAST_INSERT_ID() se actualizará a la de la tabla 2, y no a la de la tabla 1. Si aún necesita la de la tabla 1 después, tendremos que almacenarla en una variable. Esto nos lleva a las vías 2 y 3:

  2. almacenará el LAST_INSERT_ID() en una variable MySQL:

    INSERT ...
    SELECT LAST_INSERT_ID() INTO @mysql_variable_here;
    INSERT INTO table2 (@mysql_variable_here, ...);
    INSERT INTO table3 (@mysql_variable_here, ...);
    
  3. almacenará el LAST_INSERT_ID() en una variable php (o cualquier idioma que pueda conectarse a una base de datos, de su elección):

    • INSERT ...
    • Usa tu idioma para recuperar el LAST_INSERT_ID()ya sea ejecutando esa declaración literal en MySQL, o usando, por ejemplo, php’s mysql_insert_id() que hace eso por ti
    • INSERT [use your php variable here]

ADVERTENCIA

Cualquiera que sea la forma de resolver esto que elija, debe decidir qué debe suceder. si la ejecución se interrumpe entre consultas (por ejemplo, su servidor de base de datos falla). Si puedes vivir con “algunos han terminado, otros no”, no sigas leyendo.

Sin embargo, si decide “todas las consultas finalizan o ninguna finaliza; no quiero filas en algunas tablas pero no filas coincidentes en otras, siempre quiero que las tablas de mi base de datos sean consistentes”, debe envolver todas las declaraciones en una transacción. Por eso usé el BEGIN y COMMIT aquí.

Comenta de nuevo si necesitas más información 🙂

bastante simple si usa procedimientos almacenados:

call insert_user_and_profile('f00','http://www.f00.com');

guión completo:

drop table if exists users;
create table users
(
user_id int unsigned not null auto_increment primary key,
username varchar(32) unique not null
)
engine=innodb;

drop table if exists user_profile;
create table user_profile
(
profile_id int unsigned not null auto_increment primary key,
user_id int unsigned not null,
homepage varchar(255) not null,
key (user_id)
)
engine=innodb;

drop procedure if exists insert_user_and_profile;

delimiter #

create procedure insert_user_and_profile
(
in p_username varchar(32),
in p_homepage varchar(255)
)
begin
declare v_user_id int unsigned default 0;

insert into users (username) values (p_username);
set v_user_id = last_insert_id(); -- save the newly created user_id

insert into user_profile (user_id, homepage) values (v_user_id, p_homepage);

end#

delimiter ;

call insert_user_and_profile('f00','http://www.f00.com');

select * from users;
select * from user_profile;

¿Qué sucedería si desea crear muchos registros de este tipo (para registrar 10 usuarios, no solo uno)? Encuentro la siguiente solución (solo 5 consultas):

Paso I: Crear una tabla temporal para almacenar nuevos datos.

CREATE TEMPORARY TABLE tmp (id bigint(20) NOT NULL, ...)...;

A continuación, llene esta tabla con valores.

INSERT INTO tmp (username, password, bio, homepage) VALUES $ALL_VAL

Aquí, en lugar de $ALL_VAL colocas la lista de valores: (‘test1′,’test1′,’bio1′,’home1’),…,(‘testn’,’testn’,’bion’,’homen’)

Paso II: Enviar datos a la tabla ‘usuario’.

INSERT IGNORE INTO users (username, password)
SELECT username, password FROM tmp;

Aquí, se puede usar “IGNORAR”, si permite que algunos usuarios ya estén dentro. Opcionalmente, puede usar ACTUALIZAR similar al paso III, antes de este paso, para encontrar qué usuarios ya están dentro (y marcarlos en la tabla tmp). Aquí suponemos que ese nombre de usuario se declara como PRIMARY en la tabla de usuarios.

Paso III: Aplique la actualización para leer la identificación de todos los usuarios de los usuarios a la tabla tmp. ESTE ES UN PASO ESENCIAL.

UPDATE tmp JOIN users ON tmp.username=users.username SET tmp.id=users.id

Paso IV: Cree otra tabla, usando la identificación de lectura para los usuarios

INSERT INTO profiles (userid, bio, homepage) 
SELECT id, bio, homepage FROM tmp

Reseñas y calificaciones del tutorial

Si entiendes que ha resultado útil este post, te agradeceríamos que lo compartas con otros entusiastas de la programación así contrubuyes a extender nuestra información.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags : /

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *