Matriz de elementos de PostgreSQL, cada uno de los cuales es una clave externa

83

Estoy intentando crear una base de datos para mi aplicación y una cosa que me gustaría encontrar la mejor manera de hacerlo es crear una relación de uno a muchos entre mis tablas Usersy Items.

Sé que puedo hacer una tercera tabla, ReviewedItemsy que las columnas sean una Useridentificación y una Itemidentificación, pero me gustaría saber si es posible hacer una columna Users, digamos reviewedItems, que es una matriz de enteros que contiene claves externas para Itemseso el Userha revisado.

Si PostgreSQL puede hacer esto, ¡hágamelo saber! Si no es así, seguiré la ruta de mi tercera tabla.

Zach
fuente
3
Ha habido parches para agregar esta función a Postgres, consulte blog.2ndquadrant.com/… (2012) y postgresql.org/message-id/… (2017). Todavía no han sido aceptados, pero con suerte algún día.
Simon Kissane

Respuestas:

68

No, esto no es posible.

PostgreSQL es un DBMS relacional , que opera de manera más eficiente en modelos de datos correctamente normalizados. Las matrices son, por definición, conjuntos ordenados, no estructuras de datos relacionales y, por lo tanto, el estándar SQL no admite la definición de claves externas en elementos de matriz, y tampoco PostgreSQL.

Sin embargo, puede construir una base de datos perfectamente fina con elementos de matriz vinculados a claves primarias en otras tablas. Sin embargo, esos elementos de la matriz no se pueden declarar como claves externas y, por lo tanto, el DBMS no mantendrá la integridad referencial.

Patricio
fuente
3
Usted puede definir un disparador restricción de que se compruebe que. Pero no estoy seguro de si funciona de manera confiable en todos los casos.
a_horse_with_no_name
@a_horse_with_no_name: ¿podría dar un ejemplo sobre reliably in all cases? ¿Quiere decir que a veces el disparador puede fallar? Gracias.
Luan Huynh
1
@LuanHuynh: No recuerdo los detalles (técnicos), pero la última vez que se discutió esto en la lista de correo, alguien mencionó que un activador de restricción correspondiente podría no detectar todos los casos, pero eso ya no es cierto
a_horse_with_no_name
Gracias, supongo que les haré una tabla de relaciones
Zach
1
@a_horse_with_no_name ¿puedes publicar una respuesta con un ejemplo de tal restricción?
OrangeDog
65

Es posible que pronto sea posible hacer esto: https://commitfest.postgresql.org/17/1252/ - ¡Mark Rofail ha estado haciendo un excelente trabajo en este parche!

El parche (una vez completado) permitirá

CREATE TABLE PKTABLEFORARRAY (
    ptest1 float8 PRIMARY KEY,
    ptest2 text
);
CREATE TABLE FKTABLEFORARRAY (
    ftest1 int[],
    FOREIGN KEY (EACH ELEMENT OF ftest1) REFERENCES PKTABLEFORARRAY,
    ftest2 int
);

Sin embargo, el autor actualmente necesita ayuda para reajustar el parche (más allá de mi capacidad), así que cualquiera que lea esto y conozca los aspectos internos de Postgres, por favor ayude si puede.

Jarym
fuente
8
muy CALIENTE de hecho ...CREATE TABLE FKTABLEFORARRAY ( ftest1 int[], FOREIGN KEY (EACH ELEMENT OF ftest1) REFERENCES PKTABLEFORARRAY, ftest2 int )
Victor
1
El parche está esperando que el autor realice un seguimiento. Hasta que la función esté disponible, tendrá que usar el disparador para verificar la integridad, lo que puede ser lento.
yoonghm
34
lástima, no parece haber sido incluido :(
Teocali
6
2020, aún sin soporte: postgresql.org/docs/13/unsupported-features-sql-standard.html
M Imam Pratama