Hola usuario de nuestra página web, tenemos la solución a lo que buscas, continúa leyendo y la obtendrás a continuación.
Solución:
Hasta Postgres 11 columnas generadas no son compatibles, tal como se define en el estándar SQL e implementado por algunos RDBMS, incluidos DB2, MySQL y Oracle. ni el parecido “columnas calculadas” de SQL Server.
STORED
las columnas generadas se introducen con postgres 12. Ejemplo trivial:
CREATE TABLE tbl (
int1 int
, int2 int
, product bigint GENERATED ALWAYS AS (int1 * int2) STORED
);
db<>violín aquí
VIRTUAL
las columnas generadas pueden venir con una de las próximas iteraciones. (No en Postgres 13, todavía).
Relacionado:
- La notación de atributo para la llamada de función da error
Hasta entoncespuedes emular VIRTUAL
columnas generadas con un función usando attribute notación (tbl.col
) que se ve y funciona como una columna virtual generada. Esa es una rareza de sintaxis que existe en Postgres por razones históricas y resulta que encaja en el caso. Esta respuesta relacionada tiene ejemplos de código:
- ¿Almacenar consulta común como columna?
La expresión (que parece una columna) no está incluida en un SELECT * FROM tbl
, aunque. Siempre tienes que enumerarlo explícitamente.
También se puede admitir con un índice de expresión coincidente, siempre que la función sea IMMUTABLE
. Me gusta:
CREATE FUNCTION col(tbl) ... AS ... -- your computed expression here
CREATE INDEX ON tbl(col(tbl));
Alternativas
Alternativamente, puede implementar una funcionalidad similar con un VIEW
, opcionalmente junto con índices de expresión. Después SELECT *
puede incluir la columna generada.
“persistió” (STORED
) las columnas calculadas se pueden implementar con disparadores de una manera funcionalmente idéntica.
Las vistas materializadas son un concepto estrechamente relacionado, implementado desde Postgres 9.3.
En versiones anteriores, uno puede administrar los MV manualmente.
¡¡Sí tu puedes!! La solución debe ser fácil, segura y eficaz…
Soy nuevo en postgresql, pero parece que puede crear columnas calculadas usando un índice de expresión, emparejado con una vista (la vista es opcional, pero hace que la vida sea un poco más fácil).
Supongamos que mi cálculo es md5(some_string_field)
luego creo el índice como:
CREATE INDEX some_string_field_md5_index ON some_table(MD5(some_string_field));
Ahora, cualquier consulta que actúe sobre MD5(some_string_field)
utilizará el índice en lugar de calcularlo desde cero. Por ejemplo:
SELECT MAX(some_field) FROM some_table GROUP BY MD5(some_string_field);
Puede comprobar esto con explicación.
Sin embargo, en este punto confía en que los usuarios de la tabla sepan exactamente cómo construir la columna. Para hacer la vida más fácil, puede crear un VIEW
en una versión aumentada de la tabla original, agregando el valor calculado como una nueva columna:
CREATE VIEW some_table_augmented AS
SELECT *, MD5(some_string_field) as some_string_field_md5 from some_table;
Ahora cualquier consulta usando some_table_augmented
será capaz de usar some_string_field_md5
sin preocuparse por cómo funciona… simplemente obtienen un buen rendimiento. La vista no copia ningún dato de la tabla original, por lo que es buena tanto en términos de memoria como de rendimiento. Sin embargo, tenga en cuenta que no puede actualizar/insertar en una vista, solo en la tabla de origen, pero si realmente lo desea, creo que puede redirigir las inserciones y actualizaciones a la tabla de origen usando reglas (podría estar equivocado en ese último punto como Nunca lo he probado yo mismo).
Editar: parece que si la consulta involucra índices que compiten, el motor del planificador a veces puede no usar el índice de expresión en absoluto. La elección parece depender de los datos.
¡Una forma de hacerlo es con un gatillo!
CREATE TABLE computed(
one SERIAL,
two INT NOT NULL
);
CREATE OR REPLACE FUNCTION computed_two_trg()
RETURNS trigger
LANGUAGE plpgsql
SECURITY DEFINER
AS $BODY$
BEGIN
NEW.two = NEW.one * 2;
RETURN NEW;
END
$BODY$;
CREATE TRIGGER computed_500
BEFORE INSERT OR UPDATE
ON computed
FOR EACH ROW
EXECUTE PROCEDURE computed_two_trg();
El activador se activa antes de que se actualice o inserte la fila. Cambia el campo que queremos calcular de NEW
registro y luego devuelve ese registro.
valoraciones y reseñas
Si haces scroll puedes encontrar los comentarios de otros administradores, tú también tienes la habilidad dejar el tuyo si te gusta.