La mejor manera de modelar un singleton en una base de datos relacional

12

Al diseñar un esquema de base de datos relacional para aplicaciones web, a menudo encuentro un caso en el que termino creando una tabla solo para contener una fila y solo una fila. Parece que esa es la forma incorrecta de diseñarlo, pero no puedo encontrar nada significativamente mejor, o esa es obviamente "la forma correcta de hacerlo".

Un ejemplo reciente es un sitio que permite a los usuarios controlar manualmente el contenido en la página de inicio. Bueno, solo hay una página de inicio. Creé una tabla que tenía todos los campos necesarios para construir la página de inicio, como un campo de texto para un área que contenía texto descriptivo. Un campo para almacenar el nombre de un archivo de imagen grande. Algunas claves externas que apuntan a artículos que aparecerán en la página de inicio, etc. Funciona, pero se siente mal tener una tabla con solo una fila.

En el pasado, probé muchos otros diseños, como permitir varias filas en la tabla de la página de inicio y seleccionar una al azar. Intenté agregar un campo booleano llamado "activo" y seleccionar una de las páginas de inicio activas al azar. Intenté forzar solo una fila para estar activa en un momento dado en la lógica de la aplicación. He intentado ni siquiera hacer una tabla de página de inicio y tener todos los demás elementos, como artículos, para tener campos booleanos con nombres como Featured_on_homepage.

En la mayoría de los casos, podría construir la página de inicio con un montón de constantes en un archivo de configuración. El principal problema con el archivo de configuración es que está bajo control del desarrollador. Debido a que algo como el contenido de la página de inicio es algo que debe editar el usuario, debe ir a la base de datos.

En muchos sitios, no tengo este problema porque puedo crear cosas como la página de inicio con una consulta, como seleccionar los cinco artículos más nuevos. Pero cuando tengo páginas que se seleccionan manualmente con requisitos estrictos, se vuelve difícil modelarlo en la base de datos. Pero imagina que tienes una mesa de fotos y una mesa de artículos. El requisito es que la página de inicio muestre exactamente cinco fotos, exactamente tres artículos y dos bloques de texto arbitrario controlados manualmente por el usuario. ¿Cómo modelas eso en la base de datos de la manera correcta?

Además, tengo este problema de modelado en muchos otros casos además de las páginas de inicio. Es el ejemplo más fácil y generalmente aplicable que se me ocurrió.

Apreche
fuente
No está del todo claro qué problema le presenta la tabla de una sola fila, aparte de eso, de alguna manera representa un desperdicio de una tabla. ¿Estás seguro de que estás tratando de resolver un problema que realmente sufres?
David Aldridge

Respuestas:

10

Un enfoque simple sería guardar las propiedades de la página de inicio en una tabla de propiedades (o llamarla de otra manera) que se compone de columnas de nombre y valor.

HomePageProperty1 - UserValue1

HomePageProperty2 - UserValue2

Puede que no sea una solución ideal, pero es simple y flexible. También elimina la tabla con un escenario de una fila.

Walter
fuente
1
Este enfoque funciona para múltiples propósitos. Por ejemplo, almacenaré información de la versión del esquema, punteros de rotación para las cosas que deben reciclarse diariamente, etc. La información de la versión del esquema es importante al diagnosticar qué salió mal. Es una forma razonable de garantizar que se aplique un parche para una solución solo de base de datos.
Berin Loritsch
2
+1: este es el diseño exacto de la tabla que nuestro Arquitecto de datos me dio para un propósito similar.
Ali
3
El problema con este enfoque es que necesita representar diferentes tipos de variables como columnas diferentes, y tener lógica para decirle qué columna usar y cuáles son obligatorias. No puede definir que un valor booleano sea booleano, o que una fecha sea una fecha, o que un atributo particular no pueda ser nulo, o deba estar dentro de un rango particular o cumplir una condición, todas las cosas que son trivialmente simples con una mesa de una sola fila.
David Aldridge
3

No me queda claro que tienes un problema que debes resolver.

Una tabla de una sola fila no es un problema para la base de datos en sí misma, y ​​le permite aplicar tipos de datos y restricciones a los datos.

No estoy seguro de que estés tratando de resolver un problema real, para ser honesto.

David Aldridge
fuente
2

Me parece que está utilizando una base de datos para algo que en realidad debería almacenarse como un archivo.

Su descripción me recuerda muchas páginas Wiki, donde los usuarios pueden editar el contenido. En Wikis, o al menos en las implementaciones que he visto, las páginas persisten como archivos.

Esto le ayuda con otros detalles web, como permitir a sus usuarios almacenar en caché su página de inicio, que es prácticamente gratuita si almacena las páginas como archivos, pero tendría que implementar manualmente la lógica para la invalidación de caché si está creando el página en cada solicitud basada en el contenido almacenado en la base de datos.

En cualquier caso, solo quiero dejar en claro que aunque la mayoría de los datos persistentes de una aplicación se almacenan en una base de datos, no significa que debamos almacenar todo allí. Las bases de datos son solo una de las herramientas de nuestro comercio. Debemos aprender a hacer un buen uso de tantas herramientas diferentes como podamos.

MichelHenrich
fuente
2

No hay absolutamente nada de malo en una tabla con una fila.

Si esto es parte de su diseño, debe aplicarlo. Dele a la tabla una columna de identidad, dele una restricción de unicidad, luego agregue una restricción de columna para permitir solo un valor único. Esto asegurará que nadie podrá agregar una segunda fila, lo que podría ser catastrófico si las declaraciones SQL que leen la tabla (comprensiblemente) carecen de una cláusula where.

Si comienza a obtener una gran cantidad de columnas, puede verse tentado a reducir la tabla y, en cambio, tener una fila por elemento de configuración. Esta no es la mejor idea porque pierde la seguridad y la validación del tipo. Además, perdería la compatibilidad con la multitenencia , lo que podría ser importante para usted. Una mejor solución sería repensar cuáles son realmente sus entidades y tener tablas separadas de una sola fila para diferentes entidades.

Sí, no solo digo que una tabla de una sola fila está bien, sino que sugiero que desee más de una.

John Wu
fuente
1

Puede crear una tabla llamada STATIC_CONTENT y tener columnas para una clave, así como el contenido, los rastreadores activos / inactivos, etc. Luego, cree una fila con una clave de "HomePage" y en su página de inicio, cargue el contenido estático para esa clave y mostrarlo. De esa manera, cuando tenga otro contenido estático (sobre página, página de contacto, etc.), puede agregar filas a esa tabla.

RationalGeek
fuente
1

No hay nada malo per se en tener una tabla con una sola fila. Si solo tiene una instancia de una determinada entidad, entonces podría ser la forma más natural de representar esto.

Pero seleccionar una fila al azar es incorrecto y malo. Si la lógica de su dominio solo espera una sola fila, obviamente es un error en los datos si en realidad hay más. ¡Entonces debe averiguar quién o qué está escribiendo datos no válidos en la base de datos y evitar que lo hagan! Dependiendo de la base de datos, probablemente podría agregar una restricción a la tabla para evitar que esto suceda en primer lugar, por ejemplo, permitiendo solo un valor particular como la clave primaria.

JacquesB
fuente
0

Solo para agregar a Walter ..

La estructura de la tabla de propiedades debe permitir múltiples tipos de datos.

Fileds:
PropertyName
PropertyTextValue
PropertyDateValue
PropertyNumericValue
PropertyBoolValue
Imbéciles
fuente
Con esto, ¿cómo garantiza que solo se establezca un valor de propiedad por fila? Es bastante fácil aplicarlo en la aplicación, pero ¿qué pasa si alguien actualiza la base de datos manualmente y guarda algunos datos allí?
Apreche
0

Me parece que podrías haber abstraído un nivel más. Al final, una "Página de inicio" es una "Página". Puede tener diferentes tipos de páginas con las propiedades que necesita. Si tenía secciones en su sitio, probablemente necesitaría una "SectionHomePage", que puede funcionar igual que una "Página de inicio".

El requisito es que la página de inicio muestre exactamente cinco fotos, exactamente tres artículos y dos bloques de texto arbitrario controlados manualmente por el usuario. ¿Cómo modelas eso en la base de datos de la manera correcta?

Probémoslo así. Estoy agregando una tabla ArticlePage para que vea cómo puede separar las propiedades en consecuencia.

PAGES
Id
Title
Description

HOMEPAGES
PageId (FK)
PhotoListLimit
ArticleListLimit
TextBlockListLimit

ARTICLEPAGE
PageId (FK)
ArticleMainQuote
ArticleMainBody
ArticlePhoto1
ArticlePhoto2

Eso funcionaría bien para mí, incluso funcionaría muy bien para un sitio grande.

Juan Carlos Eduardo Romaina Ac
fuente