Ir al contenido

Esquema de Base de Datos

El Observatorio del Congreso usa un esquema unificado Popolo-Graph almacenado en SQLite. Contiene 12 tablas organizadas en cuatro grupos funcionales:

GrupoTablasPropósito
Entidades baseperson, organization, areaLegisladores, partidos, divisiones geográficas
Actividad legislativamotion, vote_event, vote, countIniciativas, sesiones de votación, votos individuales, recuentos
Relaciones estructuralesmembership, postAfiliaciones partidistas, cargos en comisiones
Redes de poderrelacion_poder, actor_externo, evento_politicoVínculos de lealtad, actores externos, eventos políticos

Todas las tablas usan claves primarias de texto con una convención de prefijos (ej. P00001, VE_D00001). Las claves foráneas imponen integridad referencial con ON DELETE CASCADE donde aplica. Las restricciones CHECK validan enumeraciones y rangos a nivel de base de datos.

+-------------+
| area |
+-------------+
| id (PK) |
| nombre |
| parent_id FK|----+
+-------------+ |
^ |
| |
+---------------+ +------------------+ | +------------------+
| organization | | post | | | actor_externo |
+---------------+ +------------------+ | +------------------+
| id (PK) |<---| org_id (FK) | | | id (PK) |
| nombre | | area_id (FK) |--+ | nombre |
| abbr | +------------------+ | tipo |
| clasificacion | | area_id (FK) |--+
+------+--------+ +------------------+ |
| +----------------+ |
| | membership | |
| +----------------+ |
| | id (PK) | |
+---org_id-->| person_id (FK) |-----+ |
| | rol | | |
| | on_behalf_of FK|-----+ |
| +----------------+ | |
| v |
| +-------------+ |
| | person | |
| +-------------+ |
| | id (PK) | |
| | nombre | |
| | genero | |
| +-------------+ |
| | |
| v |
| +----------------+ +-------------+ |
| | vote_event | | vote | |
| +----------------+ +-------------+ |
+--org_id| id (PK) |<--| vote_event | |
| motion_id (FK)| | voter_id FK | |
+-------+--------+ +-------------+ |
| |
v |
+-------------+ +------------------+ |
| motion | | count | |
+-------------+ +------------------+ |
| id (PK) | | id (PK) | |
| texto | | vote_event_id FK |----------+
| clasificacion | option | |
+-------------+ | group_id (FK) ---+----------+
+------------------+
+-------------------+ +-------------------+
| relacion_poder | | evento_politico |
+-------------------+ +-------------------+
| id (PK) | | id (PK) |
| source_type | | fecha |
| source_id | | tipo |
| target_type | | descripcion |
| target_id | | motion_id (FK) ---+--> motion
| tipo | +-------------------+
| peso (1-5) |
+-------------------+
source/target: person | organization | actor_externo

Todas las claves primarias usan un prefijo de texto para identificar el tipo de entidad y, donde aplica, la cámara de origen. La porción numérica se rellena con ceros a 5 dígitos.

EntidadPrefijoEjemploRelleno
Vote Event (Diputados)VE_DVE_D000015 dígitos
Vote Event (Senado)VE_SVE_S000015 dígitos
Vote (Diputados)V_DV_D000015 dígitos
Vote (Senado)V_SV_S000015 dígitos
Motion (Diputados)Y_DY_D000015 dígitos
Motion (Senado)Y_SY_S000015 dígitos
Membership (Diputados)M_DM_D000015 dígitos
Membership (Senado)M_SM_S000015 dígitos
PersonPP000015 dígitos
CountCC000015 dígitos

Estas son las organizaciones politicas principales almacenadas en la tabla organization:

IDAbreviaturaNombreClasificación
O08DiputadosCámara de Diputadosgobierno
O09SenadoCámara de Senadoresgobierno
O11MORENAMovimiento de Regeneración Nacionalpartido
O12PANPartido Acción Nacionalpartido
O13PRIPartido Revolucionario Institucionalpartido
O14PRDPartido de la Revolución Democráticapartido
O15PTPartido del Trabajopartido
O16PVEMPartido Verde Ecologista de Méxicopartido
O17MCMovimiento Ciudadanopartido

Almacena las divisiones geográficas usadas para distritos electorales y estados. Las áreas se pueden anidar mediante parent_id para modelar la jerarquía: distrito dentro de estado.

ColumnaTipoNulableDescripción
idTEXTNO (PK)Clave primaria, prefijo A01, A02
nombreTEXTNONombre del área
clasificacionTEXTNOClasificación: estado, distrito, circunscripcion
parent_idTEXTClave foránea a area(id). El distrito apunta a su estado padre
geometryTEXTGeometría GeoJSON opcional
clasificacion IN ('estado', 'distrito', 'circunscripcion')

Almacena partidos políticos, cámaras legislativas, coaliciones e instituciones de gobierno.

ColumnaTipoNulableDescripción
idTEXTNO (PK)Clave primaria, prefijo O01, O02
nombreTEXTNONombre oficial (UNIQUE)
abbrTEXTAbreviatura (MORENA, PAN, etc.)
clasificacionTEXTNOTipo: partido, bancada, coalicion, gobierno, institucion, otro
fundacionTEXTFecha de fundación en ISO 8601
disolucionTEXTFecha de disolución en ISO 8601
clasificacion IN ('partido', 'bancada', 'coalicion', 'gobierno', 'institucion', 'otro')

Tabla central de legisladores (diputados y senadores). Incluye datos demográficos, tipo de curul, corrientes internas y evaluaciones de vulnerabilidad.

ColumnaTipoNulableDescripción
idTEXTNO (PK)Clave primaria, prefijo P01, P02
nombreTEXTNONombre completo
fecha_nacimientoTEXTFecha de nacimiento en ISO 8601
generoTEXTGénero: M, F, NB
curul_tipoTEXTTipo de curul: mayoria_relativa, plurinominal, suplente
circunscripcionINTEGERNúmero de circunscripción electoral (1-5)
start_dateTEXTInicio del período legislativo
end_dateTEXTFin del período legislativo
corriente_internaTEXTCorriente interna: Monreal, AMLO, Sheinbaum, institucionalista, o NULL
vulnerabilidadTEXTVulnerabilidad política: alta, media, baja, o NULL
observacionesTEXTNotas de texto libre
identifiers_jsonTEXTObjeto JSON con IDs externos
genero IN ('M', 'F', 'NB')
curul_tipo IN ('mayoria_relativa', 'plurinominal', 'suplente')
circunscripcion BETWEEN 1 AND 5
corriente_interna IN ('Monreal', 'AMLO', 'Sheinbaum', 'institucionalista', NULL)
vulnerabilidad IN ('alta', 'media', 'baja', NULL)

membership — Relaciones Persona-Organización

Sección titulada «membership — Relaciones Persona-Organización»

Vincula personas con organizaciones incluyendo rol, rango de fechas y representación opcional de coalición.

ColumnaTipoNulableDescripción
idTEXTNO (PK)Clave primaria, prefijo M01, M02
person_idTEXTNOClave foránea a person(id), ON DELETE CASCADE
org_idTEXTNOClave foránea a organization(id), ON DELETE CASCADE
rolTEXTNORol: diputado, senador, suplente
labelTEXTDescripción legible de la membresía
start_dateTEXTNOFecha de inicio de la membresía
end_dateTEXTFecha de fin. NULL significa activa actualmente
on_behalf_ofTEXTClave foránea a organization(id). Miembro de coalición votando bajo otro partido

Representa cargos formales dentro de organizaciones (ej. presidente de comisión, secretario de mesa directiva).

ColumnaTipoNulableDescripción
idTEXTNO (PK)Clave primaria, prefijo T01, T02
org_idTEXTNOClave foránea a organization(id)
area_idTEXTClave foránea a area(id) para cargos vinculados geográficamente
labelTEXTNOTítulo del cargo
start_dateTEXTNOFecha de inicio
end_dateTEXTFecha de fin. NULL significa que el cargo aún se mantiene

Almacena propuestas legislativas incluyendo reformas constitucionales, leyes secundarias y legislación ordinaria.

ColumnaTipoNulableDescripción
idTEXTNO (PK)Clave primaria, prefijo Y01, Y02
textoTEXTNOTexto completo o resumen de la iniciativa
clasificacionTEXTNOTipo: reforma_constitucional, ley_secundaria, ordinaria, otra
requirementTEXTNOUmbral de votación requerido: mayoria_simple, mayoria_calificada, unanime
resultTEXTResultado: aprobada, rechazada, pendiente, retirada, o NULL
dateTEXTFecha de la iniciativa
legislative_sessionTEXTEtiqueta de la sesión legislativa, ej. “LXVI Legislatura”
fuente_urlTEXTURL fuente de la iniciativa
clasificacion IN ('reforma_constitucional', 'ley_secundaria', 'ordinaria', 'otra')
requirement IN ('mayoria_simple', 'mayoria_calificada', 'unanime')
result IN ('aprobada', 'rechazada', 'pendiente', 'retirada', NULL)

Registra sesiones de votación. Cada evento de votación está vinculado a una motion y una organización (cámara).

ColumnaTipoNulableDescripción
idTEXTNO (PK)Clave primaria, prefijo VE01, VE02
motion_idTEXTNOClave foránea a motion(id)
start_dateTEXTNOFecha y hora de la votación
organization_idTEXTNOClave foránea a organization(id) (cámara)
resultTEXTResultado: aprobada, rechazada, empate, o NULL
sitl_idINTEGERID de votación del SITL (Sistema de Información Legislativa)
voter_countINTEGERNúmero de votantes registrados
legislaturaTEXTCódigo de legislatura: LX, LXI, …, LXVI
requirementTEXTUmbral de votación: mayoria_simple, mayoria_calificada, unanime, o NULL
source_idTEXTID del portal original, usado para deduplicación
identifiers_jsonTEXTJSON con identificadores externos
result IN ('aprobada', 'rechazada', 'empate', NULL)
requirement IN ('mayoria_simple', 'mayoria_calificada', 'unanime', NULL)

Registra el voto individual de cada legislador dentro de un evento de votación.

ColumnaTipoNulableDescripción
idTEXTNO (PK)Clave primaria, prefijo V01, V02
vote_event_idTEXTNOClave foránea a vote_event(id)
voter_idTEXTNOClave foránea a person(id)
optionTEXTNOVoto emitido: a_favor, en_contra, abstencion, ausente
groupTEXTAfiliación partidista al momento de la votación
option IN ('a_favor', 'en_contra', 'abstencion', 'ausente')

Tallies agregadas de votos por opción y por grupo (partido). Usadas para consultas estadísticas rápidas sin escanear filas individuales de vote.

ColumnaTipoNulableDescripción
idTEXTNO (PK)Clave primaria, prefijo C01, C02
vote_event_idTEXTNOClave foránea a vote_event(id)
optionTEXTNOOpción de voto: a_favor, en_contra, abstencion, ausente
valueINTEGERNOConteo de votos para esta opción (>= 0)
group_idTEXTClave foránea a organization(id). El partido que se está contabilizando
option IN ('a_favor', 'en_contra', 'abstencion', 'ausente')
value >= 0

Almacena actores políticos fuera del legislativo que influyen en los resultados legislativos: gobernadores, alcaldes, ex presidentes, jueces, dirigentes partidistas.

ColumnaTipoNulableDescripción
idTEXTNO (PK)Clave primaria, prefijo AE01, AE02
nombreTEXTNONombre completo
tipoTEXTNOTipo de actor: gobernador, alcalde, ex_presidente, dirigente, juez, otro
area_idTEXTClave foránea a area(id). Jurisdicción geográfica
start_dateTEXTInicio del período de relevancia
end_dateTEXTFin del período de relevancia
observacionesTEXTNotas de texto libre
tipo IN ('gobernador', 'alcalde', 'ex_presidente', 'dirigente', 'juez', 'otro')

Tabla de relaciones polimórficas que modela conexiones políticas entre cualquier combinación de personas, organizaciones y actores externos. Esta es una extensión Popolo específica de este proyecto.

ColumnaTipoNulableDescripción
idTEXTNO (PK)Clave primaria, prefijo RP01, RP02
source_typeTEXTNOTipo de entidad origen: person, organization, actor_externo
source_idTEXTNOID de la entidad origen
target_typeTEXTNOTipo de entidad destino: person, organization, actor_externo
target_idTEXTNOID de la entidad destino
tipoTEXTNOTipo de relación: lealtad, presion, influencia, familiar, clientelismo, conflicto, alianza
pesoINTEGERNOPeso/fuerza de la relación (1-5)
start_dateTEXTInicio de la relación
end_dateTEXTFin de la relación
fuenteTEXTFuente de los datos de la relación
notaTEXTNotas adicionales
source_type IN ('person', 'organization', 'actor_externo')
target_type IN ('person', 'organization', 'actor_externo')
tipo IN ('lealtad', 'presion', 'influencia', 'familiar', 'clientelismo', 'conflicto', 'alianza')
peso BETWEEN 1 AND 5

Registra eventos políticos significativos que pueden afectar el comportamiento o los resultados legislativos.

ColumnaTipoNulableDescripción
idTEXTNO (PK)Clave primaria, prefijo EP01, EP02
fechaTEXTNOFecha del evento
tipoTEXTNOTipo de evento (texto libre)
descripcionTEXTNODescripción del evento
consecuenciaTEXTConsecuencias esperadas u observadas
fuente_urlTEXTURL fuente
motion_idTEXTClave foránea a motion(id). Iniciativa legislativa relacionada

Los siguientes índices están definidos para optimizar los patrones de consulta más comunes:

Nombre del ÍndiceTablaColumnas
idx_membership_personmembershipperson_id
idx_membership_orgmembershiporg_id
idx_vote_event_motionvote_eventmotion_id
idx_vote_event_sourcevote_eventsource_id
idx_vote_votervotevoter_id
idx_vote_eventvotevote_event_id
idx_count_eventcountvote_event_id
idx_count_groupcountgroup_id
idx_relacion_sourcerelacion_podersource_type, source_id
idx_relacion_targetrelacion_podertarget_type, target_id
idx_relacion_tiporelacion_podertipo
idx_person_corrientepersoncorriente_interna
idx_actor_tipoactor_externotipo

Cuatro triggers imponen consistencia de fechas entre los campos start_date y end_date:

Se ejecuta BEFORE INSERT en person. Garantiza que end_date no sea anterior a start_date cuando ambos están presentes.

CREATE TRIGGER trg_person_dates
BEFORE INSERT ON person
BEGIN
SELECT RAISE(ABORT, 'end_date must be >= start_date')
WHERE NEW.end_date IS NOT NULL
AND NEW.start_date IS NOT NULL
AND NEW.end_date < NEW.start_date;
END;

Misma validación en UPDATE de person.

CREATE TRIGGER trg_person_dates_update
BEFORE UPDATE ON person
BEGIN
SELECT RAISE(ABORT, 'end_date must be >= start_date')
WHERE NEW.end_date IS NOT NULL
AND NEW.start_date IS NOT NULL
AND NEW.end_date < NEW.start_date;
END;

Se ejecuta BEFORE INSERT en membership. Previene membresías con rangos de fechas invertidos.

CREATE TRIGGER trg_membership_dates
BEFORE INSERT ON membership
BEGIN
SELECT RAISE(ABORT, 'end_date must be >= start_date')
WHERE NEW.end_date IS NOT NULL
AND NEW.end_date < NEW.start_date;
END;

Misma validación en UPDATE de membership.

CREATE TRIGGER trg_membership_dates_update
BEFORE UPDATE ON membership
BEGIN
SELECT RAISE(ABORT, 'end_date must be >= start_date')
WHERE NEW.end_date IS NOT NULL
AND NEW.end_date < NEW.start_date;
END;

Volúmenes actuales de datos en la base de datos de producción:

MétricaValor
Votos individuales~3,510,053
Eventos de votacion~8,123
Personas~3,849
Organizaciones~20
Legislaturas cubiertas7 (LX a LXVI)