Pregunta

Estamos trabajando en el diseño de una aplicación que suele ser OLTP (piense:sistema de compras).Sin embargo, este en particular tiene la necesidad de que algunos usuarios estén desconectados, por lo que deben poder descargar la base de datos a su máquina, trabajar en ella y luego volver a sincronizarla una vez que estén en la LAN.

Me gustaría señalar que sé que esto se ha hecho antes, pero no tengo experiencia con este modelo en particular.

Una idea que pensé fue usar GUID como claves de tabla.Entonces, por ejemplo, una orden de compra no tendría un número (autonumérico) sino un GUID, de modo que cada cliente fuera de línea pueda generarlos, y no tengo conflictos cuando me conecto nuevamente a la base de datos.

¿Es esta una mala idea por alguna razón?¿Será lento el acceso a estas tablas a través de la clave GUID?

¿Ha tenido experiencia con este tipo de sistemas?¿Cómo has solucionado este problema?

¡Gracias!
Daniel

¿Fue útil?

Solución

El uso de Guids como claves principales es aceptable y se considera una práctica bastante estándar por las mismas razones por las que usted las está considerando.Se pueden usar en exceso, lo que puede hacer que la depuración y la administración sean un poco tediosas, así que trate de mantenerlas fuera de las tablas de códigos y otros datos de referencia, si es posible.

Lo que debe preocuparle es el identificador legible por humanos.Las personas no pueden intercambiar las guías. ¿Te imaginas intentar confirmar el número de tu pedido por teléfono si se trata de una guía?Entonces, en un escenario fuera de línea, es posible que aún tengas que generar algo - como una identificación del editor (estación de trabajo/usuario) y algún número de secuencia, por lo que el número de pedido puede ser 123-5678 -.

Sin embargo, es posible que esto no satisfaga los requisitos comerciales de tener un número secuencial.De hecho, los requisitos reglamentarios pueden influir: algunas reglamentaciones (tal vez SOX) exigen que los números de factura sean secuenciales.En tales casos, puede ser necesario generar una especie de número proforma que se fija más adelante cuando los sistemas se sincronizan.Es posible que obtenga tablas que tengan OrderId (Guid), OrderNo (int), ProformaOrderNo (varchar); puede aparecer cierta complejidad.

Al menos tener guías como claves principales significa que no tiene que realizar muchas actualizaciones en cascada cuando finalmente se realiza la sincronización; simplemente actualiza el número legible por humanos.

Otros consejos

@SqlMenace

Hay otros problemas con los GUID. Verá que los GUID no son secuenciales, por lo que las inserciones estarán dispersas por todas partes, lo que provoca divisiones de páginas y fragmentación del índice.

No es verdad. ¡Clave primaria! = índice agrupado.

Si el índice agrupado es otra columna (me viene a la mente "inserted_on"), las inserciones serán secuenciales y no se producirán divisiones de página ni fragmentación excesiva.

Este es un uso perfectamente bueno de los GUID.Los únicos inconvenientes serían una ligera complejidad al trabajar con GUID sobre INT y la ligera diferencia de tamaño (16 bytes frente a 4 bytes).

No creo que ninguno de los dos sea gran cosa.

¿Será lento el acceso a estas tablas a través de la tecla GUID?

Hay otros problemas con los GUID. Verá que los GUID no son secuenciales, por lo que las inserciones estarán dispersas por todas partes, lo que provoca divisiones de páginas y fragmentación del índice.

En SQL Server 2005, MS introdujo NEWSEQUENTIALID() para solucionar este problema, el único problema para usted podría ser que solo puede usar NEWSEQUENTIALID como valor predeterminado en una tabla.

Tienes razón en que este es un problema antiguo y tiene dos soluciones canónicas:

  • Utilice identificadores únicos como clave principal.Tenga en cuenta que si le preocupa la legibilidad, puede generar su propio identificador único en lugar de utilizar un GUID.Un identificador único utilizará información sobre la fecha y la máquina para generar un valor único.

  • Utilice una clave compuesta de 'Actor' + identificador.Cada usuario obtiene una ID de actor numérica y las claves de las filas recién insertadas utilizan la ID de actor así como el siguiente identificador disponible.Entonces, si dos actores insertan una nueva fila con ID "100", no se violará la restricción de clave principal.

Personalmente, prefiero el primer enfoque, ya que creo que las claves compuestas son realmente tediosas como claves externas.Creo que la queja sobre la legibilidad humana es exagerada: ¡de todos modos, los usuarios finales no deberían tener que saber nada sobre sus claves!

Asegúrese de utilizar guid.comb: se encarga de la indexación.Si después de eso se enfrenta a problemas de rendimiento, en poco tiempo se convertirá en un experto en escalamiento.

Otra razón para utilizar GUID es permitir la refactorización de la base de datos.Supongamos que decide aplicar polimorfismo o herencia o lo que sea a su entidad Clientes.Ahora desea que Clientes y Empleados deriven de Persona y que compartan una mesa.Tener identificadores realmente únicos simplifica la migración de datos.No hay secuencias ni campos de identidad de números enteros con los que luchar.

Sólo voy a señalarte ¿Cuáles son las mejoras de rendimiento de Sequential Guid sobre Guid estándar?, que cubre la charla GUID.

Para facilitar la lectura humana, considere asignar ID de máquina y luego utilizar números secuenciales de esas máquinas como posibilidad.Sin embargo, esto requerirá gestionar la asignación de ID de máquina.Podría hacerse en una o dos columnas.

Sin embargo, personalmente me gusta la respuesta de SGUID.

Las guías ciertamente serán más lentas (y usarán más memoria) que las claves enteras estándar, pero si eso es un problema o no dependerá del tipo de carga que verá su sistema.Dependiendo de su base de datos backend, puede haber problemas con la indexación de campos guid.

El uso de guids simplifica toda una clase de problemas, pero usted paga por ello en parte por el rendimiento y también por la capacidad de depuración: ¡escribir guids en esas consultas de prueba envejecerá muy rápido!

El backend será SQL Server 2005.
Frontend/Lógica de Aplicación será .Net

Además de los GUID, ¿se le ocurren otras formas de resolver la "fusión" que ocurre cuando la computadora fuera de línea sincroniza los nuevos datos con la base de datos central?
Quiero decir, si las claves son INT, básicamente tendré que volver a numerar todo al importar.Los GUID me ahorrarán eso.

El uso de GUID nos ahorró mucho trabajo cuando tuvimos que fusionar dos bases de datos en una.

Si su base de datos es lo suficientemente pequeña como para descargarla en una computadora portátil y trabajar con ella sin conexión, probablemente no necesite preocuparse demasiado por las diferencias de rendimiento entre ints y Guids.¡Pero no subestimes lo útiles que son los ints al desarrollar y solucionar problemas de un sistema!Probablemente necesitarás idear una lógica de importación/sincronización bastante compleja independientemente de si estás usando Guids o no, por lo que es posible que no te ayuden tanto como crees.

@Simón,

Planteas muy buenos puntos.Ya estaba pensando en los números "temporales" "legibles por humanos" que generaría sin conexión y que recrearía en sincronización.Pero quería evitar tener que lidiar con claves externas, etc.

¡Comenzaría a buscar SQL Server Compact Edition para esto!Ayuda con todos sus problemas.

Arquitectura de almacenamiento de datos con SQL Server 2005 Compact Edition

Está diseñado específicamente para

Solicitudes de fuerza de campo (FFA).Los FFA generalmente comparten uno o más de los siguientes atributos

Permiten al usuario realizar sus funciones de trabajo mientras se desconectan de la red de back-end, en el sitio en la ubicación de un cliente, en la carretera, en un aeropuerto o desde casa.

Los FFA generalmente están diseñados para una conectividad ocasional, lo que significa que cuando los usuarios ejecutan la aplicación del cliente, no necesitan tener una conexión de red de ningún tipo.Los FFA a menudo involucran múltiples clientes que pueden acceder simultáneamente y usar datos de la base de datos de back-end, tanto en un modo conectado como desconectado.

Los FFA deben poder replicar datos de la base de datos de back-end a las bases de datos del cliente para obtener soporte fuera de línea.También deben poder replicar registros de datos modificados, agregados o eliminados del cliente al servidor cuando la aplicación puede conectarse a la red

Primer pensamiento que me viene a la mente:¿No ha diseñado MS el modelo DataSet y DataAdapter para admitir escenarios como este?

Creo haber leído que MS cambió su modelo de conjunto de registros ADO al modelo actual de DataSet, por lo que también funciona muy bien sin conexión.Y también está esto Servicios de sincronización para ADO.NET

Creo que he visto código que utiliza el modelo DataSet que también usa claves externas y aún se sincronizan perfectamente cuando se usa DataAdapter.Sin embargo, no he probado los servicios de sincronización, pero creo que usted también podría beneficiarse de ellos.

Espero que esto ayude.

@Portman De forma predeterminada, PK == Índice agrupado, la creación de una restricción de clave principal creará automáticamente un índice agrupado; debe especificar no agrupado si no desea que esté agrupado.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top