EL MODELO DE DATOS
Cómo diseño el esquema de un sitio web tipo directorio a escala de seis cifras. Entidades, atributos, slugs, índices y las decisiones de diseño que se combinan.
← Todas las guías Todas las guías de este tema
Las decisiones sobre el esquema que se acumulan
El éxito o el fracaso de un sitio web de directorio con 28 000 filas (HostList.io) o 137 000 filas (Not Another Sunday) depende de las decisiones sobre el esquema que se tomen durante la primera semana. Las decisiones más importantes son: cómo se normalizan las entidades, cómo se almacenan los atributos, cómo se generan los slugs y qué se indexa.
Cada uno de estos aspectos es reversible a pequeña escala, pero su corrección resulta prohibitivamente cara cuando se trata de cifras de seis cifras. Asegúrate de hacerlas bien desde el principio.
Entidades, atributos, uniones
Una tabla de entidades con una fila maestra por empresa, lugar o producto. Clave primaria UUID estable, una columna por atributo intrínseco (nombre, año_de_fundación, mercado_principal). Evita meter los atributos en columnas JSON en este nivel; deben poder consultarse como columnas de primer orden.
Una tabla de atributos por cada eje ortogonal: categorías (cada fila corresponde a una categoría), regiones (cada fila corresponde a una región) y niveles de precio (cada fila corresponde a un nivel). Estas son las dimensiones según las cuales se agrupan las entidades.
Relaciones «muchos a muchos» mediante tablas de enlace: entity_categories, entity_regions, entity_features. Nunca almacenes listas de categorías separadas por comas en la tabla de entidades; las tablas de enlace son las que permiten que el filtrado, la visualización de listas y el recuento se realicen con rapidez.
Las babosas son eternas
Una vez que Google ha indexado una página de directorio, el slug no debe cambiar. Utiliza la generación determinista de slugs a partir del nombre de la entidad, con gestión de colisiones mediante un sufijo numérico: nginx-hosting, nginx-hosting-2 si se produce una colisión.
Mantén una tabla independiente llamada «slug_history» que asigne cada slug histórico al slug canónico actual. Cuando sea necesario cambiar el nombre de una entidad (corrección, cambio de marca), se generará el nuevo slug canónico, el slug antiguo se añadirá a la tabla de historial y se configurará automáticamente una redirección 301 permanente.
Las consecuencias de no configurar correctamente la estabilidad de los slugs en una web con 28 000 filas son catastróficas: cada cadena de redireccionamientos que se crea supone una pequeña pérdida de posicionamiento, y no hay soluciones eficaces a posteriori.
Indexabilidad a nivel de fila
Añade una columna booleana indexable a la tabla de entidades, con el valor predeterminado «true», cuya lógica la cambie a «false» cuando la entidad no cumpla los umbrales de calidad (contenido único insuficiente, falta de atributos obligatorios, ausencia de enlaces internos entrantes).
La consulta del mapa del sitio aplica un filtro cuando «indexable» = «true». El renderizador de páginas añade la etiqueta meta «noindex» cuando «indexable» = «false». Ambos se derivan de la misma columna, por lo que se mantienen sincronizados de forma atómica.
En HostList.io, aproximadamente 18 000 de las 28 000 entidades son indexables en un momento dado. Las otras 10 000 se pueden rastrear, pero no indexar, lo que mantiene limpia la superficie indexada y refuerza el resto de las páginas indexadas.
Índices que importan
Índice sobre el slug para la búsqueda de renderización de páginas. Índice sobre (indexable, last_updated_at) para la consulta del mapa del sitio. Índice sobre (category_id, indexable) en la tabla de unión para las páginas de listado de categorías. Índice sobre (region_id, indexable) para las páginas regionales.
A escala de cientos de miles de filas, una consulta de renderizado de página sin índices tarda unos segundos. Con los índices adecuados, tarda milisegundos. El impacto en el tiempo de compilación se acumula: 28 000 renderizados de página a 100 ms cada uno suponen 47 minutos; a 10 ms cada uno, suponen 5 minutos.
Ejecuta EXPLAIN ANALYZE en todas las consultas de renderización de páginas a gran escala. El planificador de consultas predeterminado se equivoca en las uniones en forma de directorio con más frecuencia de lo que cabría esperar.