Saltar al contenido

Columnas computadas/calculadas/virtuales/derivadas en PostgreSQL

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.

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



Utiliza Nuestro Buscador

Deja una respuesta

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