web-dev-qa-db-fra.com

Utiliser l'UUID en plus de l'ID d'incrémentation automatique

J'essaie de concevoir le schéma DB de mon nouveau projet et j'ai besoin de quelques suggestions. Je pense avoir une colonne supplémentaire pour certaines tables qui est un UUID. Je voulais principalement des tables contenant des données accessibles via REST, donc je ne veux pas exposer la clé primaire. Ma préoccupation est que lorsque je veux mettre à jour une table, je dois exécuter une requête de plus juste pour prendre la clé primaire d'origine.

Qu'est-ce que tu penses?

7
pik4

Le plus grand mythe lors de la conception d'applications est que vous ne pouvez avoir qu'une seule clé.

Ayez plusieurs clés, allez-y et faites-le. Votre application est autorisée à avoir une clé primaire différente de votre base de données; Je sais que cela peut sembler étrange au début, mais vous obtenez le meilleur des deux mondes en suivant cette voie.

Les UUID présentent de nombreux avantages, mais constituent des index cluster généralement horribles. Ainsi, vous pouvez simplement utiliser un int comme index PK/cluster dans votre base de données, mais également avoir un autre index unique sur votre colonne d'ID externe. Cela peut nécessiter une jointure supplémentaire pour de nombreuses requêtes, mais ce n'est pas grave, car dans les bases de données relationnelles, les jointures internes sur les colonnes int auto-incrémentées sont extrêmement rapides.

Un autre avantage de cette approche à double clé est la possibilité de distribuer facilement et géographiquement votre base de données. Étant donné que les UUID sont globalement uniques, deux bases de données géographiquement séparées n'auront pas à ralentir la coordination de leurs clés, tant que vous vous assurez que le DB int PK ne quitte jamais la base de données et n'est pas utilisé par le service de repos.

Voici un autre point, votre identifiant externe n'a même pas besoin d'être un UUID, il peut également y avoir d'autres options.

L'extérieur peut également être un entier, ou une chaîne, ou la clé naturelle de l'entité; n'importe quoi. Cela rendrait vos URL moins laides qu'un UUID

N'ayez pas peur d'avoir plusieurs clés, masquer votre clé DB à vos consommateurs d'api de repos est une bonne chose.


Le plus grand nombre de clés que j'ai jamais utilisées est de deux, mais dans la bonne situation, je peux imaginer que jusqu'à quatre sont justifiées (clé DB, clé d'application, clé métier, clé client)

8
TheCatWhisperer

Il est inutile d'avoir deux clés primaires.

  1. Les UUID sont lents à indexer.

Non ils ne sont pas. Arrêtez de vous soucier des nombres obscurs comme les pages et la fragmentation et faites des tests.

https://www.mssqltips.com/sqlservertip/5105/sql-server-performance-comparison-int-versus-guid/

http://byterot.blogspot.com/2013/02/performance-series-guids-vs-identity-rdbms-sql.html

https://www.cybertec-postgresql.com/en/int4-vs-int8-vs-uuid-vs-numeric-performance-on-bigger-joins/

Dans tous les cas, si vous avez à la fois et indexez l'UUID alors vous avez le même problème

  1. Les UUID occupent plus d'espace. eh bien oui, tant que vous pouvez vous en sortir avec ces faibles nombres max.

Dans tous les cas, si vous avez les deux c'est nettement plus grand

  1. Les UUID sont moches. Eh bien, vous ne voudriez pas en taper un, mais voulez-vous taper 13243444444431 ou Gdih £ $% d1? si vous avez besoin d'une jolie URL pour le référencement ou pour toute autre raison, il existe de meilleures solutions que d'ajouter plus de colonnes id à votre table.

Les entrées séquentielles ont des problèmes majeurs qui sont résolus avec les UUID, dont l'un consiste à deviner l'ID suivant ou le nombre de commandes que vous avez prises.

Ce sont de réelles préoccupations commerciales et de sécurité et devraient, à elles seules, suffire à justifier de ne pas utiliser du tout les entrées auto_inc.

N'essayez pas de corriger les problèmes avec des solutions hacky, remplacez-les simplement par la norme de l'industrie.

5
Ewan

Si votre seul objectif est de cacher la clé primaire de votre interface REST, alors je vous déconseille. Au lieu de cela, le cryptage de vos clés serait une bonne solution pour cela.

1

C'est un problème courant que je me suis souvent rencontré. J'ai fini par emprunter la route "il suffit d'utiliser un numéro pour l'identifiant", ce qui signifie que ce n'est pas aussi laid pour les clients de voir ces UUID.

La seule autre façon, comme vous l'avez déjà évoqué, est de masquer cet ID derrière une sorte de requête, dans laquelle vous devrez alimenter les paramètres afin de récupérer l'UUID correct, cependant, cela signifie que vous pouvez tout aussi bien utiliser ces paramètres comme clé primaire pour la table!

Je dirais qu'il n'y a aucun moyen de faire REST (c'est-à-dire le transfert d'état d'un modèle) sans être en mesure d'identifier l'instance que vous RESTing, donc vous allez avoir besoin d'une clé, quelle que soit forme que prend cette clé.

Si votre problème est dû à la sécurité, je vois le problème tel qu'il est dans votre code de validation de message du serveur, pas que le client voit les ID. Si un pirate veut charger des données de votre table, il n'aura pas besoin d'identifiants pour le faire. Et vous devriez également valider les demandes, de sorte qu'aucune substance douteuse ne parvienne à vos couches métier de toute façon, c'est-à-dire l'authentification et l'autorisation des messages.

Pour revenir à votre question:

"accessible via REST, donc je ne veux pas exposer la clé primaire"

Je pense que c'est le contraire, vous avez besoin d'exposer la clé primaire afin de faire REST.

EDIT: Comme l'a souligné @Murph, cela donne réellement aux attaquants une meilleure chance si vous donnez des identifiants au client - je ne savais pas cela. Il se peut que d'autres réponses ici (je regarde la plus courte disant de crypter la clé) soient plus adaptées à votre situation. Edit 2: Il semble que les UUID ne soient pas plus sûrs que les entiers ...

1
Dan Rayson

Le problème avec l'utilisation des clés primaires comme identifiant public pour votre entité est que vous divulguez des détails de votre solution de stockage de données à vos clients (et par conséquent, tout au long de votre application). Cela peut avoir des implications sur la sécurité, tout en signifiant que les modifications apportées au backend de vos applications peuvent être plus complexes. Les UUID permettent de résoudre ce problème en fournissant un identifiant alternatif entièrement indépendant de la technologie de votre base de données.

Les UUID ne sont qu'une solution à ce problème, avec l'avantage inhérent que, à toutes fins pratiques, ils sont garantis d'être uniques. Cependant, si vous avez fait l'effort d'utiliser autre chose que la clé primaire comme identifiant, vous pourriez trouver que l'utilisation d'une chaîne arbitraire ou simplement d'un autre identifiant numérique fournit des URL plus agréables.

Une autre considération est que si vous utilisez des GUID/UUID comme identifiant public pour votre entité, vous aurez probablement besoin d'une sorte d'index pour eux. Étant donné qu'ils occupent beaucoup plus d'espace que les entiers, votre index sera beaucoup plus grand.

1
richzilla