2012-09-04 23 views
7

Actualmente estoy trabajando en un proyecto que implica el almacenamiento de datos en una base de datos SQL-Lite HTML5. Actualmente, tengo un esquema de la siguiente manera (4): TablasSincronización de la base de datos de la aplicación HTML5

TransData: 
----------------------------------------------------------- 
| TID | UserName | TransColor | ... | Date | Note | 
----------------------------------------------------------- 
| 6 | Brendan |  Red | ... |  |  | 
----------------------------------------------------------- 
| 7 | Brendan |  Red | ... |  |  1 | 
----------------------------------------------------------- 

FullData: 
----------------------------------------------------------- 
| TID | UserName | TransColor | ... | Date | Note | 
----------------------------------------------------------- 
| 1 | Brendan |  Red | ... |  | Start | 
----------------------------------------------------------- 
| ... | Brendan |  Red | ... |  |  | 
----------------------------------------------------------- 
| 40 | Brendan |  Red | ... |  | End | 
----------------------------------------------------------- 

SalamanderData: 
---------------------------------------------------- 
| SID | SalamanderName | Length | ... | TID | 
---------------------------------------------------- 
| 1 | Northern-Slimy | 16 | ... | 6 | 
---------------------------------------------------- 
| 2 | Two-Lined | 26 | ... | 6 | 
---------------------------------------------------- 
| 3 | Two-Lined | 12 | ... | 7 | 
---------------------------------------------------- 

SalamanderData: 
---------------------------------------------------- 
| SID | SalamanderName | Length | ... | TID | 
---------------------------------------------------- 
| 1 | Northern-Slimy | 16 | ... | 6 |  
---------------------------------------------------- 
| 2 | Two-Lined | 26 | ... | 6 | 
---------------------------------------------------- 
| 3 | Two-Lined | 12 | ... | 7 | 
---------------------------------------------------- 

Nota: La columna "Nota" en Transdata se utiliza para señalar el punto de datos a partir de una colección en el campo FullData.

La base de datos entre mi aplicación y el servidor NO DEBE ESTAR EN SINCRONIZACIÓN. Estoy simplemente tratando de volcar todas estas tablas en la base de datos en el servidor (y por volcado quiero decir, actualizar las referencias a otras tablas, y luego insertarlas en la base de datos del servidor).

Iba a usar MAX(TID-Server) + TID-App = new TID-Server, y conecte las actualizaciones en cascada en las tablas.

¿Cómo vas a hacer esto?

+0

¿Alguien puede ayudar? No puedo encontrar la manera de escribir una consulta de inserción que primero coloque en cascada las actualizaciones de los elementos insertados. – Brendan

+0

Muestra SalamanderData dos veces. Si entiendo su pregunta correctamente, tiene 4 tablas "del lado del cliente" con un esquema de tabla similar a lo que es "del lado del servidor". Las tablas no están sincronizadas ni estarán sincronizadas, pero en ocasiones debe enviar los contenidos de las 4 tablas del "lado del cliente" al servidor donde se actualizarán o insertarán, según corresponda. El gran desafío son las claves primarias, que por supuesto no estarán sincronizadas (o peor aún, pueden duplicarse). ¿Está esto cerca? –

+0

Eso es exactamente. Y sí, accidentalmente copié mi tabla SalamanderData dos veces; se supone que es una tabla BugData, que muestra el recuento de varios errores, como ciempiés y milpiés. Necesito actualizar las claves principales en la inserción para que se sincronicen con la tabla y entre sí. – Brendan

Respuesta

6

Según el comentario de Dan Pichelman, el problema es que el cliente inserta registros en la base de datos local y, para hacerlo, tiene que determinar las claves principales para ellos. Pero, dado que todos los diferentes clientes hacen lo mismo, los nuevos PK chocarán cuando lleguen al servidor.

Este es un problema común en sistemas que están físicamente desconectados (al menos algunas veces) o donde no puede haber un solo punto de falla, como en un generador de secuencia compartido.

Algunas soluciones comunes son:

GUID

Aquí el PK es un número aleatorio de 128 bits (o más grande). La probabilidad de que dos PK cualquiera sean iguales es excesivamente pequeño. Pero para reducir aún más el cambio de colisión, el algoritmo GUID incluye siembra con identificadores de máquina únicos (el MAC de red) y tiempo. Dos GUID producidos en la misma máquina nunca colisionarán, y tampoco los GUID producidos en máquinas con MAC diferentes. La mayoría de las máquinas e idiomas tienen funciones nativas para generar GUID, pero JavaScript no.Ver:

Una partición esquema de nombres

En este esquema, el PK es una vez más un gran número (campo de bits en realidad), y de crear particiones en una forma jerárquica Un buen ejemplo es el sistema telefónico internacional (al menos antes de los números portátiles). Aquí el número de teléfono se divide en:

  • Código de país: por ejemplo, EE.UU. - 1 código de
  • Área: por ejemplo, Sunnyvale - Número 615
  • suscriptor, controlado por el intercambio.

En su caso, es posible dividir el número por:

  • de inicio de sesión del usuario (por ejemplo, un número único a cada usuario)
  • ID de sesión (por ejemplo, un número único a cada inicio de sesión por usuario, para distinguir entre diferentes sesiones del mismo usuario pero en diferentes navegadores/ordenadores)
  • número de serie

Combinando los tres que tendrá una gu PK único garantizado

'licencia' Servidor PK

Las primeras dos sugerencias tienen el mérito de que funcionan completamente desconectado. Si tiene un cliente conectado, podría tener un servicio web que suministre PK cuando el cliente lo solicite.

Para mayor eficiencia, podría devolver un lote de, digamos, 100 números. Esto incluso podría devolverse cuando el usuario inicie sesión.

El cliente puede usarlas todas y solicitar más. Puede haber casos en los que el cliente olvide el estado y deje un "agujero" en la secuencia global de PK. Esto seguramente no sería una preocupación.

Algunas consideraciones

A veces te pueden gustar PK secuenciales para fines ordenan de la tabla. En ese caso, ¿necesita ordenar por cliente o en el momento de la creación? Si alguno de ellos es importante, puede calificar el esquema de nombres de la partición más alto. Coloque el cliente o la hora como la primera partición según corresponda. Alternativamente, agregue más columnas a su tabla.

Si no desea la estructura fija del esquema de nombres de partición, el GUID funcionará bien.

Si desea una coordinación central, use el servidor de licencias PK.

0

no sé una manera estéticamente agradable de hacer esto, pero yo "resuelto" por la escritura de procedimientos almacenados:

La primera tabla es fácil - actualización o inserción, según sea necesario. Si realiza una inserción, obtenga la clave primaria del registro recién insertado y luego procese las tablas dependientes en consecuencia (lo que generalmente significa insertar datos con la nueva clave primaria). Repita según sea necesario a medida que avanza en las relaciones. Para 4 tablas, debería estar bien, pero odiaría hacerlo por 40.

En mi caso, era complicado e involucraba tablas de búsqueda temporales con oldPK y newPK en ellas.

También fue un tedioso poco & código cuya única función es que funciona.

0

Esto va un poco en contra de lo que ha pedido, así que solo comente si esto está totalmente fuera de línea y lo eliminaré.Pero no especificó ninguna razón particular de por qué el servidor/cliente no puede estar sincronizado con respecto a la clave principal (que en mi opinión es realmente el problema aquí).

También estoy asumiendo (de sus datos, y su pregunta) que estamos hablando de una aplicación web con contenido creado por el usuario (como un registro) que ocasionalmente se carga en el servidor.

Por lo tanto, solo para deportes, ¿ha considerado usar una clave principal construida por varios campos? De esta forma, podría tener incrementos automáticos en su base de datos local, volcar los datos en el servidor y no colisionaría con los datos de otros usuarios. Un ejemplo de la tabla SalamanderData sería algo en la línea de:

CREATE TABLE SalamanderData 
(
    SID int NOT NULL, 
    SalamanderName varchar(255), 
    Length int, 
    ... ..., 
    TID int NOT NULL, 
    CONSTRAINT pk_SDataEntry PRIMARY KEY (SID,TID) 
) 

Que a su vez crearía una PK de SID y TID.

lectura a través de mi correo y comprobar las otras respuestas, me doy cuenta de que esto es lo que Andrew ha sugerido, por lo que incluso si esto le ayuda, realmente debería aceptar su respuesta

mantener la respuesta a los efectos de posiblemente aclarar la solución y dar un ejemplo de código

Cuestiones relacionadas