Me parece muy común querer modelar datos relacionales en mis programas funcionales. Por ejemplo, al desarrollar un sitio web que puede querer tener la siguiente estructura de datos para almacenar información sobre mis usuarios:Modelado seguro de datos relacionales en Haskell
data User = User
{ name :: String
, birthDate :: Date
}
A continuación, quiero para almacenar datos acerca de los mensajes de los usuarios publican en mi sitio:
data Message = Message
{ user :: User
, timestamp :: Date
, content :: String
}
hay varios problemas asociados con esta estructura de datos:
- no tenemos ninguna manera de distinguir a los usuarios con nombres similares y fechas de nacimiento.
- Los datos del usuario se duplicarán en la serialización/deserialización
- La comparación de los usuarios requiere la comparación de sus datos, lo que puede ser una operación costosa.
- Las actualizaciones de los campos
User
son frágiles; puede olvidarse de actualizar todas las ocurrencias deUser
en su estructura de datos.
Estos problemas son manejables mientras que nuestros datos se pueden representar como un árbol. Por ejemplo, se puede refactorizar así:
data User = User
{ name :: String
, birthDate :: Date
, messages :: [(String, Date)] -- you get the idea
}
Sin embargo, es posible tener sus datos en forma de un DAG (imaginar una relación de muchos a muchos), o incluso como un gráfico general (OK, tal vez no). En este caso, tiendo a simular la base de datos relacional mediante el almacenamiento de mis datos en Map
s:
newtype Id a = Id Integer
type Table a = Map (Id a) a
Este tipo de obras, pero no es seguro y fea por múltiples razones:
- Usted está a sólo una
Id
llamada de constructor lejos de búsquedas sin sentido. - En la búsqueda obtiene
Maybe a
, pero a menudo la base de datos garantiza estructuralmente que hay un valor. - Es torpe.
- Es difícil garantizar la integridad referencial de sus datos.
- Administrar índices (que son muy necesarios para el rendimiento) y garantizar su integridad es aún más difícil y torpe.
¿Existe trabajo para superar estos problemas?
Parece que Template Haskell podría resolverlos (como suele ocurrir), pero me gustaría no reinventar la rueda.
no el modelo que se muestra aquí compartir todas las desventajas de uno a muchos del modelo original de la pregunta? – ehird
@ehird, realizo alrededor de 10 ediciones por minuto, así que creo que he respondido a tu preocupación en el camino. – dflemstr
Sí, de hecho. (Por cierto, el estado ácido en realidad no depende de ixset; están diseñados para usarse juntos). – ehird