Arquitectura de Datos
La base de datos utiliza PostgreSQL como motor principal,
aprovechando sus capacidades para el manejo de tipos
JSONB y búsqueda de texto completo (Full-Text Search). El
diseño se centra en la relación muchos-a-muchos entre normas e instituciones.
┌──────────────┐ ┌─────────────────────────────────┐ ┌────────────┐
│ tipos_normas │<────────│ normas │<────────│ descargas │
│ │ N : 1 │ │ N : 1 │ │
└──────────────┘ └─────────────────────────────────┘ └────────────┘
▲
│ N : 1
│
┌─────────────────────────────────┐
│ normas_instituciones │
└─────────────────────────────────┘
│
│ N : 1
▼
┌─────────────────────────────────┐
│ instituciones │
└─────────────────────────────────┘
La relación central es normas ↔ instituciones,
resuelta mediante la tabla pivot normas_instituciones.
Tablas del Sistema
normas
Almacena los metadatos estructurados y el contenido procesado de cada norma legal.
| Columna | Tipo | Descripción |
|---|---|---|
| id | INTEGER (PK) | ID original de la BCN |
| id_tipo | INTEGER (FK) | Referencia a tipos_normas |
| titulo | TEXT | Título oficial (indexado GIN) |
| contenido_texto | TEXT | Texto plano extraído |
| metadata_json | JSONB | Metadatos flexibles y dinámicos |
| hash_xml | VARCHAR(32) | MD5 para control de cambios |
instituciones
Entidades gubernamentales que agrupan normativas.
| Columna | Tipo | Descripción |
|---|---|---|
| id | INTEGER (PK) | ID de institución en la BCN |
| nombre | TEXT | Nombre oficial de la institución |
| fecha_agregada | TIMESTAMP | Fecha de registro en el sistema |
descargas
Log histórico de todas las operaciones de sincronización y descarga.
| Columna | Tipo | Descripción |
|---|---|---|
| id | SERIAL (PK) | ID autogenerado |
| estado | VARCHAR | "exitosa" o "error" |
| error_mensaje | TEXT | Traza del error en caso de falla |
Decisiones de Diseño
IDs de la BCN como Claves Primarias
Se utilizan los IDs originales de la BCN para normas e instituciones. Esto elimina la necesidad de
tablas de mapeo y simplifica los upserts durante la sincronización
masiva.
Uso de JSONB para Metadatos
Dado que la estructura de los metadatos de la BCN varía
según el tipo de norma (materias, organismos, tratados),
JSONB permite flexibilidad sin penalizar el rendimiento
de búsqueda gracias a los índices GIN.
Detección de Cambios (Hash MD5)
Antes de actualizar una norma en la base de datos, se compara el hash MD5 del XML descargado con el almacenado. Si son idénticos, se evita el I/O innecesario, optimizando drásticamente los procesos de sincronización masiva.
Full-Text Search
La búsqueda en el sistema utiliza la configuración de idioma spanish de PostgreSQL para manejar
stemming y stop-words.
-- Creación del índice para búsqueda rápida
CREATE INDEX idx_normas_titulo
ON normas USING gin(to_tsvector('spanish', titulo));
-- Ejemplo de consulta interna
SELECT id, titulo FROM normas
WHERE to_tsvector('spanish', titulo) @@ plainto_tsquery('spanish', 'medio ambiente')
OR titulo ILIKE '%medio ambiente%';
La consulta combina FTS para eficiencia semántica con un fallback ILIKE para garantizar coincidencias literales exactas.
Resumen de Índices
| Tabla | Índice | Tipo | Propósito |
|---|---|---|---|
| normas | idx_normas_titulo | GIN | Búsqueda rápida por título |
| normas | idx_normas_tipo | B-tree | JOIN con tipos_normas |
| normas | idx_normas_estado | B-tree | Filtro de vigencia |
| tipos_normas | idx_tipos_normas_nombre | B-tree | Búsqueda por nombre único |