este problema se puede tratar de diversas formas, pero te compartimos la que en nuestra opinión es la solución más completa.
Solución:
MySQL actualmente no admite índices condicionales.
Para conseguir lo que pides (no es que debas hacerlo 😉 ) puedes empezar creando una tabla auxiliar:
CREATE TABLE `my_schema`.`auxiliary_table` (
`id` int unsigned NOT NULL,
`name` varchar(250), /* specify the same way as in your main table */
PRIMARY KEY (`id`),
KEY `name` (`name`)
);
Luego agrega tres disparadores en la tabla principal:
delimiter //
CREATE TRIGGER example_insert AFTER INSERT ON main_table
FOR EACH ROW
BEGIN
IF NEW.status = 'ACTIVE' THEN
REPLACE auxiliary_table SET
auxiliary_table.id = NEW.id,
auxiliary_table.name = NEW.name;
END IF;
END;//
CREATE TRIGGER example_update AFTER UPDATE ON main_table
FOR EACH ROW
BEGIN
IF NEW.status = 'ACTIVE' THEN
REPLACE auxiliary_table SET
auxiliary_table.id = NEW.id,
auxiliary_table.name = NEW.name;
ELSE
DELETE FROM auxiliary_table WHERE auxiliary_table.id = OLD.id;
END IF;
END;//
CREATE TRIGGER example_delete AFTER DELETE ON main_table
FOR EACH ROW
BEGIN
DELETE FROM auxiliary_table WHERE auxiliary_table.id = OLD.id;
END;//
delimiter ;
Nosotros necesitamos
delimiter //
porque queremos usar;
dentro de los gatillos.
De esa forma, la tabla auxiliar contendrá exactamente los ID correspondientes a las filas de la tabla principal que contienen el string “ACTIVO”, siendo actualizado por los disparadores.
Para usar eso en un select
puedes usar el habitual join
:
SELECT main_table.* FROM auxiliary_table LEFT JOIN main_table
ON auxiliary_table.id = main_table.id
ORDER BY auxiliary_table.name;
Si la tabla principal ya contiene datos, o en caso de que hagas alguna operación externa que cambie los datos de forma inusual (EG: fuera de MySQL), puedes arreglar la tabla auxiliar con esto:
INSERT INTO auxiliary_table SET
id = main_table.id,
name = main_table.name,
WHERE main_table.status="ACTIVE";
Sobre el rendimiento, probablemente tendrá inserciones, actualizaciones y eliminaciones más lentas. Esto puede tener algún sentido solo si realmente trata con pocos casos en los que la condición deseada es positiva. Incluso de esa manera, probablemente solo probando puede ver si el espacio ahorrado realmente justifica este enfoque (y si realmente está ahorrando espacio).
Si Entiendo la pregunta correctamente, creo que lo que lograría lo que está tratando de hacer es crear un índice en ambas columnas, NOMBRE y ESTADO. Eso le permitiría consultar de manera eficiente donde NAME=’SMITH’ y STATUS=’ACTIVE’
No puede hacer una indexación condicional, pero para su ejemplo, puede agregar un índice de varias columnas en (name
,status
).
Aunque indexará todos los datos en esas columnas, aún lo ayudará a encontrar los nombres que está buscando con el estado “activo”.
Te mostramos las comentarios y valoraciones de los usuarios
Si guardas algún recelo o capacidad de renovar nuestro sección puedes añadir una referencia y con mucho placer lo ojearemos.