Dois-je utiliser la chaîne de bits PostgreSQL?

18

J'ai appris bit stringrécemment sur le type de données et je suis assez curieux de savoir:

  1. Au bas de cette page doc, il y a la phrase:

    ... plus 5 ou 8 octets de surcharge en fonction de la longueur de la chaîne

  2. Comment les chaînes de bits sont-elles gérées dans d'autres langages tels que PHP, Java, C #, C ++, etc., via des pilotes comme Npgsql, ODBC, etc.

Pour la question n ° 1, l'utilisation de smallint ou bigint sera beaucoup plus efficace en termes de stockage et offrirait peut-être un gain de performances puisque les entiers sont pris en charge partout. La plupart des langages de programmation gèrent facilement les opérations binaires sur les entiers. Si tel est le cas, à quoi bon introduire le type de données chaîne de bits? Est-ce uniquement pour les cas qui nécessitent une grande quantité de masques de bits? L'indexation des champs de bits peut-être? Je suis plus curieux de savoir comment l'indexation des champs binaires est effectuée dans PostgreSQL.

Pour le # 2, je suis confus, plus que curieux. Par exemple, que se passe-t-il si je stocke des masques de bits de jour de la semaine dans un champ de bit (7), un bit pour une journée, le bit le plus bas représentant le lundi. Ensuite, je demande la valeur en PHP et C ++. Que vais-je recevoir? La documentation indique que j'aurai une chaîne de bits, mais une chaîne de bits n'est pas quelque chose que je peux utiliser directement - comme avec les entiers. Alors dans ce cas, dois-je abandonner le champ de bits?

Quelqu'un peut-il expliquer pourquoi et quand utiliser un bit ou un bit variable?

Jackey Cheung
la source
2
La réponse d'Erwin sur SO est excellente (et si cela ne vous dérange pas de la copier sur @Erwin, il serait utile de l'avoir ici), mais je voudrais ajouter ma propre prudence: dans la plupart des cas, vous n'envisageriez pas de stocker des informations dans les chaînes de bits sur un SGBDR - en utilisant des colonnes booléennes distinctes dans la solution normale, quelle que soit «l'efficacité» du stockage.
Jack Douglas
@JackDouglas: Cela ne me dérangerait pas de copier ma réponse. Je me demande cependant: la duplication d'une réponse sur les sites SE est-elle une bonne idée?
Erwin Brandstetter du
@Erwin Je ne vois pas pourquoi - il y a un certain chevauchement entre les sites et ils sont tous deux censés être autonomes (donc, par exemple, nous ne le ferions pas - et de toute façon nous ne pourrions pas - fermer une question ici en double s'il y avait une question identique sur SO). Nous nous concentrons davantage sur les questions «d'experts», mais l'OMI votre réponse correspond à cette catégorie telle qu'elle est :)
Jack Douglas
@JackDouglas: Eh bien, c'est logique. Et comment pourrais-je être en désaccord après les éloges que vous avez glissés, de toute façon? ;)
Erwin Brandstetter

Réponses:

18

Si vous n'avez que quelques variables, je considérerais de garder des booleancolonnes séparées .

  • L'indexation est facile. En particulier, les index sur les expressions sont faciles.
  • Les conditions pour les requêtes et l'indexation partielle sont faciles à écrire et à lire et significatives.
  • Une colonne booléenne occupe 1 octet. Pour seulement quelques variables, cela occupe le moins d'espace.
  • Contrairement aux autres options, les colonnes booléennes autorisent des NULLvaleurs pour des bits individuels si vous en avez besoin. Vous pouvez toujours définir des colonnes NOT NULLsi vous ne le faites pas.

Optimiser le stockage

Si vous avez plus d'une main pleine de variables mais moins de 33, une integercolonne peut vous servir le mieux. (Ou un bigintpour jusqu'à 64 variables.)

  • Occupe 4 octets sur le disque.
  • Indexation très rapide pour les correspondances exactes ( =opérateur).
  • La gestion des valeurs individuelles peut être plus lente / moins pratique qu'avec bit stringou boolean.

Avec encore plus de variables, ou si vous voulez beaucoup manipuler les valeurs, ou si vous n'avez pas d'énormes tables et que l'espace disque / RAM n'est pas un problème, ou si vous ne savez pas quoi choisir, je considérerais bit(n)oubit varying(n) .

Exemples

Pour seulement 3 bits d'informations, les booleancolonnes individuelles se débrouillent avec 3 octets, une integernécessite 4 octets et bit string6 octets (5 + 1).

Pour 32 bits d'information, un a integerencore besoin de 4 octets, un bit stringoccupe 9 octets pour le même (5 + 4) et les booleancolonnes occupent 32 octets.

Lectures complémentaires

Erwin Brandstetter
la source
Oui je suis d'accord avec toi. Actuellement, j'utilise samllint pour stocker le masque de bits des jours de la semaine. Il convenait au boîtier, efficacité de stockage / performance large. Cependant, si j'avais plus d'indexation / filtrage sur les masques de bits, cela échouera, en raison de faibles performances.
Jackey Cheung
3

Tous les types PostgreSQL sont utiles pour certaines choses et moins utiles pour d'autres. En général, vous tirez le meilleur parti du souci de la fonctionnalité en premier et des performances plus tard. PostgreSQL dispose d'un grand nombre de fonctions pour manipuler différents types de types de données et celles-ci ne font pas exception.

Je m'attendrais à ce que la couche application, à moins que votre pilote de base de données ne la gère par une sorte de conversion de type, vous obtiendrez une représentation de chaîne et devrez gérer cela. Il peut donc être utile ou non à ce titre.

Il est probablement utile de sélectionner des enregistrements basés sur des opérations au niveau du bit, comme un bit ou ou un bit et et, ou de manipuler les données dans les requêtes SQL. À moins que vous ne le fassiez, la plupart des fonctionnalités plus ésotériques de PostgreSQL sont moins utiles.

Notez également que pour les chaînes d'informations binaires plus longues, il existe une grande interface d'objet qui vous permet de faire du streaming, etc. et une interface bytea qui permet une représentation de chaîne plus compacte.

tl; dr: Si vous en avez besoin, vous le saurez. Sinon, rangez-le dans la section "réservé pour une utilisation future" de votre esprit.

Chris Travers
la source