Comment choisir entre les UUID, les clés autoincrement / séquence et les tables de séquence pour les clés primaires de base de données?

Je regarde les avantages et les inconvénients de ces trois méthodes primaires pour trouver des clés primaires pour les lignes de base de données.

Donc, en supposant que j'utilise une base de données qui supporte plus d'une de ces méthodes, y a-t-il une heuristique simple pour déterminer quelle serait la meilleure option pour moi?

Comment des considérations telles que les masters distribués/multiples, les exigences de performance, L'utilisation D'ORM, la sécurité et les tests ont-elles sur le choix?

Tous les inconvénients inattendus que l'on pourrait exécuter dans?

23
demandé sur Tim 2011-01-10 03:06:40

1 réponses

Uuid

À moins que ceux-ci ne soient générés "en séquence monotone croissante", ils peuvent considérablement blesser/fragmenter les index. La prise en charge de la génération D'UUID varie selon le système. Bien que utilisable, Je n'utiliserais pas un UUID comme index/PK cluster primaire dans la plupart des cas. Si nécessaire, je ferais probablement une colonne secondaire, peut-être indexée, peut-être pas.

Certaines personnes affirment que les UUID peuvent être utilisés pour générer/fusionner des enregistrements en toute sécurité à partir d'un nombre arbitraire de systèmes. Alors qu'un UUID (selon la méthode) a généralement une chance astronomiquement faible de collision, il est possible de -- au moins avec une entrée extérieure ou très malchance:) -- générer des collisions. Je suis convaincu que seul un true PK devrait être transmis entre les systèmes, ce qui, je dirais, n'est pas (ou ne devrait pas être) un UUID généré par la base de données dans la plupart des cas.

Auto-incrémentation / clés de séquence et tables de séquence

Cela dépend vraiment de ce que la base de données supporte bien. Certaines bases de données prennent en charge des séquences plus flexibles qu'un simple "auto-incrément". Cela peut ou peut ne pas être souhaitable(ou peut être le seul moyen pour ce genre de tâche simplement, même). Les tables de séquences sont généralement plus flexibles, mais si ce type de" flexibilité " est nécessaire, je serais tenté de revenir en arrière et de visiter le modèle de conception, surtout si cela implique l'utilisation de déclencheurs. Bien que je n'aime pas les "ORM limitatifs", cela peut aussi faire une différence dans le choix du " plus simple" incrémentation automatique ou types de séquence / support de base de données.

Quelle que soit la méthode utilisée, lors de l'utilisation de clés primaires de substitution, la vraie clé primaire doit toujours être identifiée et encodée dans le schéma.

En outre, je soutiens que les "compromis de sécurité en exposant une séquence automatique PK" résultent de l'exposition incorrecte d'une propriété de base de données interne. Bien qu'un moyen très simple de gérer le fonctionnement CRUD, je crois qu'il existe une distinction entre le clés internes et les clés exposées (par exemple, joli numéro de client).

Juste mes deux cents.

Edit , réponses supplémentaires à Tim:

Je pense que la question PK générée vs vraie est une très bonne et que je dois également considérer. Je voudrais UUIDs en général aux points que vous faites. Mon hésitation était en taille Vs un int / long. N'était pas au courant des dé-optimisations d'indexation potentielles, ce qui est une préoccupation beaucoup plus importante pour moi.

Je ne m'inquiéterais pas vraiment de la taille - si un UUID est le meilleur, alors c'est le meilleur. Si ce n'est pas le cas, alors ce n'est pas le cas. Dans le schéma global les 12 octets supplémentaires sur un int ne feront probablement pas beaucoup de différence. SQL Server 2005 + prend en charge la fonction de génération D'UUID newsequentialid pour éviter la fragmentation associée à la génération d'UUID normale. La page parle de certains. Je suis sûr que d'autres bases de données ont des solutions similaires.

Et par "encodé dans le schéma", voulez-vous dire plus que l'ajout d'une contrainte d'unicité?

Oui. La clé primaire ne doit pas être la seule contrainte [unique]. Le simple fait d'utiliser un PK de substitution ne signifie pas que le modèle de base de données doit être compromis :-) des index supplémentaires peuvent également être utilisés pour couvrir, etc.

Et par "distinction entre", dites-vous que les clés primaires de substitution ne fuient jamais?

Le libellé de mon message initial était un peu dur. Ce n'est pas" jamais "autant que"s'ils le font et qu'il importe alors c'est un autre problème". Souvent, les gens se plaignent de l'insécurité à travers des nombres devinables-par exemple, si votre commande est 23, Il y a probablement une commande 22 et 24, etc. Si c'est votre "protection" et/ou peut fuir des informations sensibles, le système est déjà défectueux. (La séparation des identifiants internes et externes ne résout pas intrinsèquement ce problème et l'Authentification / autorisation est toujours requise. Cependant, c'est un problème élevé contre l'utilisation de "IDs séquentiels" - je trouve que l'encodage d'un nonce dans des URL distribuées gère plutôt bien ce pour mon cas d'utilisation.)

Plus à ce que je voulais vraiment faire passer : juste parce que l'ID PK de substitution se trouve être 8942 ne signifie pas que c'est l'ordre 8942. C'est-à-dire, conformément à la conception" certains champs sont internes uniquement à la base de données", l'ordre "number" peut être entièrement sans rapport sur la surface (mais entièrement pris en charge dans le modèle DB), comme "#2010-42c" ou autre est logique pour les exigences de l'entreprise (s). C'est ce nombre externe qui devrait être exposé dans la plupart des cas.

Je pense que parfois la clé générée est vraiment la vraie clé primaire car d'autres champs sont mutables (par exemple. l'utilisateur peut changer l'e-mail et nom d'utilisateur).

Cela peut être le cas dans une base de données et je ne discuterai pas de cette déclaration. Cependant, une fois de plus, estimant que les PK de substitution sont internes à la base de données, assurez-vous simplement de n'exporter / importer que des tuples qui peuvent être bien identifiés. Si le nom d'utilisateur / E-Mail peut changer, cela pourrait très bien inclure un UUID attribué lors de la création du compte-et pourrait très bien être le PK de substitution lui-même.

Bien sûr, comme pour tout, restez ouvert et adaptez le modèle au problème, pas le problème au modèle : -) pour un service comme twitter, par exemple, ils utilisent leur propre schéma de génération de numéros. Voir la nouvelle génération D'ID de Twitter . Contrairement à [certains] Génération D'UUID, l'approche de twitter (en supposant que tous les serveurs sont correctement configurés) garantit qu'aucune des machines/processus distribués ne générera jamais D'ID en double, ne nécessite que 64 bits et maintient un ordre approximatif (les bits les plus significatifs sont horodatés). (Le nombre d'enregistrements générés par twitter ne peut en aucun cas être lié aux exigences locales; -)

Codage heureux.

24
répondu 2011-10-15 07:37:18