Question

Nous travaillons sur la conception d'une application typiquement OLTP (pensez :système d’achat).Cependant, celui-ci en particulier nécessite que certains utilisateurs soient hors ligne, ils doivent donc pouvoir télécharger la base de données sur leur machine, travailler dessus, puis se synchroniser une fois qu'ils sont sur le réseau local.

Je voudrais noter que je sais que cela a déjà été fait, je n'ai tout simplement pas d'expérience avec ce modèle particulier.

Une idée à laquelle j'ai pensé était d'utiliser les GUID comme clés de table.Ainsi, par exemple, un bon de commande n'aurait pas de numéro (autonumérique) mais plutôt un GUID, afin que chaque client hors ligne puisse les générer, et je n'ai pas de conflits lorsque je me reconnecte à la base de données.

Est-ce une mauvaise idée pour une raison quelconque ?L'accès à ces tables via la clé GUID sera-t-il lent ?

Avez-vous eu de l'expérience avec ce type de systèmes?Comment avez-vous résolu ce problème ?

Merci!
Daniel

Était-ce utile?

La solution

L'utilisation de Guids comme clés primaires est acceptable et est considérée comme une pratique assez standard pour les mêmes raisons que vous les envisagez.Ils peuvent être surutilisés, ce qui peut rendre les choses un peu fastidieuses à déboguer et à gérer, alors essayez de les garder hors des tables de codes et autres données de référence si possible.

La chose dont vous devez vous préoccuper est l’identifiant lisible par l’homme.Les guides ne peuvent pas être échangés par des personnes. Pouvez-vous imaginer essayer de confirmer votre numéro de commande par téléphone s'il s'agit d'un guide ?Ainsi, dans un scénario hors ligne, vous devrez peut-être toujours générer quelque chose - comme un identifiant d'éditeur (poste de travail/utilisateur) et un numéro de séquence, le numéro de commande peut donc être 123-5678 -.

Cependant, cela peut ne pas satisfaire aux exigences commerciales liées à l'existence d'un numéro séquentiel.En fait, les exigences réglementaires peuvent avoir une influence : certaines réglementations (SOX peut-être) exigent que les numéros de facture soient séquentiels.Dans de tels cas, il peut être nécessaire de générer une sorte de numéro pro forma qui sera fixé ultérieurement lors de la synchronisation des systèmes.Vous pouvez vous retrouver avec des tables ayant OrderId (Guid), OrderNo (int), ProformaOrderNo (varchar) - une certaine complexité peut s'infiltrer.

Au moins, avoir des guides comme clés primaires signifie que vous n'avez pas besoin de faire beaucoup de mises à jour en cascade lorsque la synchronisation finit par se produire - vous mettez simplement à jour le numéro lisible par l'homme.

Autres conseils

@SqlMenace

Il y a d'autres problèmes avec les GUID, vous voyez que les GUID ne sont pas séquentiels, donc les insertions seront dispersées partout, ce qui provoque des fractionnements de pages et une fragmentation de l'index.

Pas vrai. Clé primaire != index clusterisé.

Si l'index clusterisé est une autre colonne ("inserted_on" me vient à l'esprit), alors les insertions seront séquentielles et aucune division de page ni fragmentation excessive ne se produira.

Il s’agit d’une très bonne utilisation des GUID.Les seuls inconvénients seraient une légère complexité dans l'utilisation des GUID sur des INT et la légère différence de taille (16 octets contre 4 octets).

Je ne pense pas que l’un ou l’autre soit un gros problème.

L'accès à ces tables via la clé GUID sera-t-il lent?

Il y a d'autres problèmes avec les GUID, vous voyez que les GUID ne sont pas séquentiels, donc les insertions seront dispersées partout, ce qui provoque des fractionnements de pages et une fragmentation de l'index.

Dans SQL Server 2005, MS a introduit NEWSEQUENTIALID() pour résoudre ce problème. Le seul problème pour vous pourrait être que vous ne pouvez utiliser NEWSEQUENTIALID que comme valeur par défaut dans une table.

Vous avez raison, il s'agit d'un vieux problème et il a deux solutions canoniques :

  • Utilisez des identifiants uniques comme clé primaire.Notez que si vous êtes préoccupé par la lisibilité, vous pouvez créer votre propre identifiant unique au lieu d'utiliser un GUID.Un identifiant unique utilisera des informations sur la date et la machine pour générer une valeur unique.

  • Utilisez une clé composite de 'Acteur' + identifiant.Chaque utilisateur reçoit un identifiant d'acteur numérique et les clés des lignes nouvellement insérées utilisent l'identifiant d'acteur ainsi que le prochain identifiant disponible.Ainsi, si deux acteurs insèrent tous deux une nouvelle ligne avec l'ID « 100 », la contrainte de clé primaire ne sera pas violée.

Personnellement, je préfère la première approche, car je pense que les clés composites sont vraiment fastidieuses en tant que clés étrangères.Je pense que la plainte en matière de lisibilité humaine est exagérée : de toute façon, les utilisateurs finaux ne devraient rien savoir de vos clés !

Assurez-vous d'utiliser guid.comb - s'occupe de l'indexation.Si vous rencontrez ensuite des problèmes de performances, vous deviendrez rapidement un expert en mise à l’échelle.

Une autre raison d'utiliser les GUID est d'activer la refactorisation de la base de données.Supposons que vous décidiez d'appliquer le polymorphisme ou l'héritage ou autre à votre entité Clients.Vous souhaitez maintenant que les clients et les employés dérivent de Person et qu'ils partagent une table.Avoir des identifiants vraiment uniques simplifie la migration des données.Il n'y a pas de séquences ou de champs d'identité entiers avec lesquels se battre.

Je vais juste vous indiquer Quelle est l’amélioration des performances du Guid séquentiel par rapport au Guid standard ?, qui couvre la présentation GUID.

Pour une meilleure lisibilité, envisagez d'attribuer des ID de machine, puis d'utiliser éventuellement des numéros séquentiels de ces machines.Cela nécessitera cependant de gérer l’attribution des ID de machine.Cela pourrait être fait sur une ou deux colonnes.

Cependant, j'aime personnellement la réponse SGUID.

Les guides seront certainement plus lents (et utiliseront plus de mémoire) que les clés entières standard, mais le fait que ce soit un problème ou non dépendra du type de charge que votre système verra.En fonction de votre base de données backend, il peut y avoir des problèmes avec l'indexation des champs GUID.

L'utilisation de guids simplifie toute une classe de problèmes, mais vous payez pour cela en partie en termes de performances et également de débogage - taper des guids dans ces requêtes de test vieillira très vite !

Le backend sera SQL Server 2005
Frontend / Application Logic sera .Net

Outre les GUID, pouvez-vous penser à d'autres moyens de résoudre la « fusion » qui se produit lorsque l'ordinateur hors ligne synchronise les nouvelles données dans la base de données centrale ?
Je veux dire, si les clés sont des INT, je devrai tout renuméroter lors de l'importation.Les GUID m'épargneront cela.

L'utilisation de GUID nous a permis d'économiser beaucoup de travail lorsque nous avons dû fusionner deux bases de données en une seule.

Si votre base de données est suffisamment petite pour être téléchargée sur un ordinateur portable et utilisée hors ligne, vous n'avez probablement pas besoin de trop vous soucier des différences de performances entre les ints et les Guids.Mais ne sous-estimez pas l’utilité des ints lors du développement et du dépannage d’un système !Vous devrez probablement proposer une logique d'importation/synchronisation assez complexe, que vous utilisiez ou non des Guids, ils pourraient donc ne pas vous aider autant que vous le pensez.

@Simon,

Vous soulevez de très bons points.Je pensais déjà aux nombres « temporaires » « lisibles par l'homme » que je générerais hors ligne, que je recréerais lors de la synchronisation.Mais je voulais éviter de faire avec des clés étrangères, etc.

je commencerais à regarder SQL Server Compact Edition pour cela !Cela vous aide à résoudre tous vos problèmes.

Architecture de stockage de données avec SQL Server 2005 Compact Edition

Il est spécialement conçu pour

Applications des forces de terrain (FFA).Les FFAS partagent généralement un ou plusieurs des attributs suivants

Ils permettent à l'utilisateur d'effectuer ses fonctions de travail tout en étant déconnectés du réseau back-end - sur le site sur un site client, sur la route, dans un aéroport ou à domicile.

Les FFAS sont généralement conçus pour une connectivité occasionnelle, ce qui signifie que lorsque les utilisateurs exécutent l'application client, ils n'ont pas besoin d'avoir une connexion réseau d'aucune sorte.Les FFAS impliquent souvent plusieurs clients qui peuvent simultanément accéder et utiliser des données à partir de la base de données back-end, à la fois en mode connecté et déconnecté.

Les FFAS doivent être en mesure de reproduire les données de la base de données back-end aux bases de données des clients pour la prise en charge hors ligne.Ils doivent également être en mesure de reproduire des enregistrements de données modifiés, ajoutés ou supprimés du client vers le serveur lorsque l'application est en mesure de se connecter au réseau

Première pensée qui me vient à l'esprit :MS n'a-t-il pas conçu le modèle DataSet et DataAdapter pour prendre en charge des scénarios comme celui-ci ?

Je crois avoir lu que MS a modifié son modèle de jeu d'enregistrements ADO pour le modèle DataSet actuel afin qu'il fonctionne également très bien hors ligne.Et il y a aussi ça Services de synchronisation pour ADO.NET

Je crois avoir vu du code qui utilise le modèle DataSet qui utilise également des clés étrangères et qui se synchronise toujours parfaitement lors de l'utilisation du DataAdapter.Je n'ai cependant pas essayé les services de synchronisation, mais je pense que vous pourriez également en bénéficier.

J'espère que cela t'aides.

@Portman Par défaut PK == Clustered Index, la création d'une contrainte de clé primaire créera automatiquement un index clusterisé, vous devez spécifier non clusterisé si vous ne souhaitez pas qu'il soit clusterisé.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top