11
votes

Stocker SHA1 Signature comme clé primaire dans PostgreSQL

J'écris un système de gestion de contenu simple. Je dois stocker des valeurs de hachage SHA1 calculées à l'extérieur comme clé primaire de ma plus grande table.

Je peux évidemment utiliser une séquence en tant que clé primaire et indexer la chaîne hexagonale SHA1 pour la recherche ... Cependant, je cherche une solution plus élégante, où je vais simplement utiliser les valeurs calculées de 20 octets SHA1 comme clé donnée aux lignes, je suis sur le point d'insérer / supprimer / la mise à jour dans la table de base de données. Existe-t-il un type de stockage efficace que je peux utiliser pour stocker et ultérieurement d'utiliser les touches SHA1 comme touches primaires?

Je aurais évidemment besoin de postgres pour prendre en charge les valeurs de 20 octets comme des clés pour que cela soit fait.

Quelqu'un avec des idées?


2 commentaires

BTW, gardez simplement à l'esprit que toutes les clés de hachage peuvent entrer en collision, même SHA1.


Je ne m'inquiéterais pas des collisions de hachage avec une bonne implémentation de SHA1 :) Voir Stackoverflow.com/Questtions/297960/...


3 Réponses :


3
votes

Vous pouvez soit convertir en heex ou base64 et utiliser une colonne varchar ou essayez de le stocker simplement dans une colonne byTea -typed. J'essaierais de faire des tables avec un tas de valeurs aléatoires dans les deux formats et de voir comment ils se produisent.

voir Les documents PostgreSQL sur BYTEA pour info sur ce type.


0 commentaires

0
votes

Soyez prudent avec ce que cela peut faire à votre index btrees. Étant donné que le SHA1 ne sera pas séquentiel, vos écrivies seront très lentes en raison de tous les sauts dans la Breee.

Si une séquence ne fonctionnera pas, je recommanderais généralement un GUID / UUID séquentiel (voir la nouvelle suiteide de SQL Server () par exemple) de quelque sorte.

Si vous voulez faire le SHA1 votre clé primaire après avoir connu cela, vous pouvez le convertir en un format hexagonal standard que SHA1 est généralement indiqué (le rend facile à taper). Je ne recommanderais pas de format binaire car vous ne serez pas en mesure de le taper pour le débogage, etc.


6 commentaires

Écrit sur un B-Tree sera séquentiel de toute façon, c'est la recherche de la page de lier avec celle-ci sautera. Cependant, même la distribution des valeurs rendra l'arbre plus équilibré et la recherche plus rapide, pas plus lente.


Je suppose que je faisais référence à la façon dont certains serveurs de base de données commandent des pages en fonction de l'index en cluster, mais c'est SQL Server, je ne sais pas si elle s'applique à PGSQL. Hmm! Mais tu as raison, l'arbre sera très bien équilibré (presque parfaitement)


@wojo : Même avec des tables en cluster, SQL Server conserve un B-Tree ordre, pas l'ordre physique. Les lignes ne sont pas nécessairement ordonnées physiquement, seulement logiquement. msdn.microsoft.com/en-us/library/ms177443 (SQL.90) .aspx


@Quassnoi Hmm, je crois comprendre qu'avec un indice en cluster que les pages sur disque sont commandées conformément à l'index et avec des valeurs aléatoires aime les GUID ou les SHA1, vous vous retrouverez à la fois avec une fragmentation logique et physique à partir de fissures de page sur des inserts . N'est-ce pas vrai? Questions similaires pour Guids (qui s'appliquerait à n'importe quel hachage): Stackoverflow.com/search?q=clustered+index+Guid


@wojo : Les insertions de valeurs séquentielles n'entraîneront pas la page des fissures de page, mais entraîneront un B-arbores B-arbores non analymétrié (en réalité, un arbre B + ). Il n'existe aucune chose comme une "fragmentation logique" dans un index arborese B + B + (page-fragmentée de la page par conception afin que vous puissiez toujours parcourir la liste liée pour accéder à la page suivante). Cette liste liée indiquera la page suivante (en ordre physique) lorsque les valeurs sont séquentielles et à une page aléatoire (probablement loin) si elles ne le sont pas.


Mais vous ne devriez obtenir que sur la page suivante lors de la recherche d'une autre valeur: si vous faites une recherche EQ-ref ( id = valeur ), une page est suffisante . Une fragmentation physique n'est donc que mal lorsque vous faites des requêtes de la plage ( entre le début et l'extrémité ) qui ne seront jamais utilisées pour SHA1 hachage. Lorsque vous ne faites pas les recherches comme ça (et que vous ne ferez jamais pour SHA1 HASHES), avoir un arbre équilibré est plus important que d'avoir des rangées contiguës logiquement contigus physiquement (ce qui est le point de valeurs séquentielles).



6
votes

En particulier si vous effectuez des paramètres binaires dans la DB (par libpq par exemple), utilisez BYTEA. Si vous souhaitez effectuer beaucoup de manipulation grâce à de simples requêtes de texte, convertissez en heext et stockez dans une colonne de texte ou de varchar.

PostgreSQL ne posera bien sûr aucun problème en général avec 20 clés d'octets, à part cela que la surcharge de performance est bien sûr supérieure à celle d'une séquence.


0 commentaires