2012-03-25 12 views
5

Tengo 2 tablas, table_a y table_b.MySQL INSERT o SELECCIONAR

CREATE TABLE `table_a` (
`ID` int(11) unsigned NOT NULL AUTO_INCREMENT, 
`val` varchar(64) NOT NULL, 
PRIMARY KEY (`ID`), 
UNIQUE KEY `val` (`val`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 

CREATE TABLE `table_b` (
`ref_a` int(11) unsigned NOT NULL, 
`data` int(11) unsigned NOT NULL, 
UNIQUE KEY `unique_index` (`ref_a`,`data`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 

Me gustaría insertar MASS en la Tabla B con un valor de referencia a ref_a Identificación de la Tabla A.

Esto es lo que estoy tratando de lograr:

SELECT ID FROM table_a WHERE val = "123" 

Si el valor no existe, a continuación, insertar el valor

INSERT INTO table_a(val) VALUES("123") 

Ahora que tengo el ID (asumir que es "1"), quiero insertar int o table_b:

INSERT INTO table_b(ref_a, data) VALUES(1, 75) 

El problema aparece cuando quiero hacerlo a granel. ¿Disminuirá mi rendimiento si alterno entre SELECTS e INSERTS en lugar de hacer una inserción masiva, luego selecciono a granel?

que podía hacer:

INSERT INTO table_b(ref_a, data) VALUES((SELECT ID FROM table_a WHERE value="123"), 75) 

pero, ¿y si el valor falta y necesito hacer una inserción anterior.

No puedo COMENZAR TRANSACCIÓN y COMPROMISO, lo que me obliga a recuperar la ID de la tabla A después de insertarla.

También puede hacer:

  • granel insertar en la tabla A.
  • Seleccionar todos los ID de la tabla A.
  • insertar en la tabla B el uso de identificadores seleccionados.

Pero estoy buscando una manera alternativa.

¿Cuál sería la forma más EFICIENTE de lograr lo que estoy tratando de hacer?

+1

¿De dónde vienen estos valores ('123',' 75')? ¿Otra mesa? ¿Una aplicación? ¿Un archivo? –

+0

¿Es 'a.ID' único y un campo de incremento automático? – SenorAmor

+0

valores 123, 75 vienen de otra tabla, tengo acceso a esos valores. a.ID es único, auto incremento sí – nick

Respuesta

1

que sugerimos utilizar un procedimiento almacenado que va a hacer la comprobación de una inserción correcta: stored routine

Será algo así como

CREATE PROCEDURE insertdata(IN i_value VARCHAR(32), IN i_data INT(11)) 
BEGIN 
DECLARE v_insertID INT DEFAULT -1; 

SELECT ID INTO v_insertID FROM table_a WHERE value = i_value; 

IF -1 = v_insertID 
THEN 
    INSERT INTO table_a(value) VALUES(i_value); 
    SELECT ID INTO v_insertID FROM table_a WHERE value = i_value; 
END IF; 

IF -1 != v_insertID 
THEN 
    INSERT INTO table_b(ref_a, data) VALUES(v_insertID, i_data); 
END IF; 

END 

Comprobamos si existe una entrada con valor dado, si no lo creamos, recuperamos la ID de entrada de creación y luego insertamos los datos en la tabla_b (si realmente se creó la entrada)

Así que solo tiene que llamar a la rutina de php para cada entrada.Será mucho más optimizado que hacerlo todos aquellos prueba en php (lo que requerirá más de una llamada mysql)

+0

esto es justo lo que necesito. Intenté crear una función antes pero fallé. ¡Gracias! veremos qué tan bien funciona – nick

3

En primer lugar asegúrese de que tiene una UNIQUE INDEX en la columna de valores en TABLE_A, y luego hacer un mayor INSERT IGNORE

INSERT IGNORE INTO table_a(value) VALUES("123"), ("345"), ("afasd"), ("#$#$%"), ... 

Ahora está seguro de que todos los valores están en table_a y puede usar de forma segura su método bulk_b insert.