
Buscar claves foráneas candidatas entre pares declarados
Source:R/coleccion.R
relaciones_coleccion.RdCorre detectar_relaciones() sobre los pares de tablas que se declaren, y
devuelve las relaciones candidatas junto con la cobertura de los pares que no
se pudieron comparar.
Usage
relaciones_coleccion(
coleccion,
pares,
muestra = 10000,
umbral_cobertura = 0.9,
orden = NULL,
tope_cache_mb = 512,
columnas_candidatas = NULL,
podar = FALSE,
tope_memoria_mb = 512
)Arguments
- coleccion
Objeto creado por
coleccion().- pares
Data frame con columnas
tabla_1ytabla_2. Cero filas es una declaración válida de «ningún par».- muestra
Filas traídas por tabla para comparar, y el mismo tope con que se calcula cada cobertura: se reenvía a
detectar_relaciones(). Sin reenviarlo valía el tope por omisión de esa función, así que conmuestra > 1e5el objeto publicaba como evidencia las filas leídas y calculaba la cobertura sobre un submuestreo que no declaraba en ningún campo: la fila llegaba a contradecirse a sí misma, conn_valores_comunescontado sobre la lectura entera junto a una cobertura calculada sobre la mitad.- umbral_cobertura
Cobertura mínima para informar una relación.
- orden
Columnas para
ORDER BY: un vector de texto que se aplica a todas las tablas, o una lista nombrada por identificador de tabla. Sin él la lectura no es repetible y el objeto lo declara.- tope_cache_mb
Presupuesto de memoria para la caché de lecturas, en megabytes. Al agotarse se sigue leyendo sin cachear y
metalo declara.- columnas_candidatas
Lista nombrada por identificador de tabla. Cada vector declara las columnas que pueden participar; una tabla no nombrada conserva todas sus columnas.
- podar
Si se aplican las podas que cambiarían lo informado —tipos incompatibles y cardinalidades imposibles—, tal como en
detectar_relaciones().FALSEpor omisión; la poda cierta por rangos disjuntos del universo se aplica siempre porque no cambia ninguna fila.- tope_memoria_mb
Presupuesto de memoria para resultados de relaciones, en megabytes. Al agotarse, las combinaciones pendientes se declaran en
cobertura_podasy los pares pendientes encobertura_pares.
Details
Los pares se declaran, igual que la frontera. Con mil tablas hay casi un
millón de pares dirigidos, así que explorar todos no es una opción cara sino
una opción imposible. estimar_costo_coleccion() permite verlo antes.
Cada tabla se lee una sola vez. Los pares repetidos se descartan, los
pares de una tabla consigo misma se rechazan, y las lecturas se guardan en
una caché con presupuesto de memoria declarado: dos pares que comparten una
tabla ya no la leen dos veces. meta$lecturas deja el SQL exacto, la vía
usada, las filas leídas y el momento de cada lectura.
El orden no se supone. Sin orden, una lectura acotada devuelve un
subconjunto arbitrario y el resultado declara meta$estable = FALSE. Declarar
columnas de orden hace la lectura repetible.
Cada par se compara sobre una muestra de filas de cada tabla, y el resultado declara ese alcance: una relación candidata sobre una muestra no es una clave foránea comprobada, es un indicio que hay que confirmar contra el diccionario de datos.
El alcance se declara por par y en la fila. Cada relación publica
filas_leidas_1/filas_leidas_2 —cuántas se compararon—, y además
filas_totales_1/filas_totales_2 y muestreado_1/muestreado_2: cuando la
lectura fue completa, el total de la tabla es exacto; cuando quedó truncada,
el total va NA y muestreado vale TRUE, porque lo único que se sabe es
que hay más filas que el tope. Publicar el tope como si fuera el total sería
decir que se leyó todo. Para saberlo se pide una fila más que el tope, que
cuesta mucho menos que un COUNT(*) por tabla y contesta exacto; esa fila de
sobra no viaja al resultado.
Antes, lo único que sobrevivía eran los atributos de detectar_relaciones()
del primer par publicado —rbind() conserva los del primer argumento—,
con etiquetas tabla1/tabla2 que no nombran a ningún par: con dos pares
decían muestreado = FALSE mientras el segundo había leído 10.000 filas de
20.000. Esos atributos ya no viajan en relaciones; lo que decían vive en las
columnas, una por par, y el conteo de pares en meta, que cuenta todos.
Las columnas candidatas se podan antes de materializar cada comparación. Las
podas quedan declaradas en cobertura_podas, con su motivo y conteo.
La poda cierta por rangos usa MIN y MAX sobre el universo completo de
cada tabla, no sobre las filas de la muestra. Si el motor no puede entregar
ese rango, la comparación sigue sin aplicar esa poda.
El campo detalle de una poda por rangos disjuntos no publica extremos que
identifiquen: si el mínimo o el máximo de un lado llega al piso de la
protección —seis caracteres o más—, ese rango sale como [valor protegido].
El mínimo de una columna de documentos es el documento de una persona real, y
el par mínimo–máximo acota además a todos los valores intermedios.
Examples
if (requireNamespace("RSQLite", quietly = TRUE) &&
requireNamespace("DBI", quietly = TRUE)) {
con <- DBI::dbConnect(RSQLite::SQLite(), ":memory:")
DBI::dbWriteTable(con, "personas", data.frame(id = 1:20, nombre = letters[1:20]))
DBI::dbWriteTable(con, "visitas", data.frame(persona_id = c(1:15, 1:5)))
col <- coleccion(con, c("personas", "visitas"), nombre = "padron")
relaciones_coleccion(
col, pares = data.frame(tabla_1 = "personas", tabla_2 = "visitas"),
columnas_candidatas = list(personas = "id", visitas = "persona_id"),
orden = list(personas = "id", visitas = "persona_id")
)
DBI::dbDisconnect(con)
}