web-dev-qa-db-fra.com

Avantages et inconvénients de l'utilisation de masques de bits dans la base de données

Il n'y a pas si longtemps, j'ai parlé à mon collègue et il était définitivement contre l'utilisation de masques de bits car il est difficile de comprendre toutes les valeurs stockées dans la base de données. À mon avis, ce n'est pas toujours une mauvaise idée de les utiliser, par exemple pour déterminer les rôles de l'utilisateur actuel. Sinon, vous devez le stocker dans une table distincte, ce qui entraînera une autre JOIN. Pouvez-vous me dire si je me trompe? Y a-t-il d'autres effets secondaires, avantages/inconvénients de l'utilisation de masques de bits?

22
Alex Ovechkin

Je travaille avec une application qui utilise des masques de bit pour stocker les attributions de rôles utilisateur. C'est une douleur dans le cul. Si cela me rend partial, coupable comme accusé.

Si vous utilisez déjà une base de données relationnelle, il s'agit d'un anti-modèle qui viole la plupart des théories relationnelles et toutes les règles de normalisation. Lorsque vous créez votre propre stockage de données, ce n'est peut-être pas une si mauvaise idée.

Il y a une telle chose que trop de tables sont jointes, mais des bases de données relationnelles sont construites pour gérer cela. Beaucoup ont des fonctionnalités supplémentaires si les performances deviennent un problème: index, vues indexées, etc. Même si les valeurs que vous recherchez ne changent pas très souvent, ce qui est un avantage pour Bitmask, la surcharge de gestion de l'indexation est assez facile sur la base de données.

Bien que la base de données fasse un bon travail d'agrégation de données, elles peuvent devenir lentes lorsque vous commencez à introduire des choses comme des formules complexes ou des fonctions scalaires dans des ensembles de données. Vous pouvez le faire au niveau du bit dans votre application, mais si tout ce que vous faites est d'obtenir des données connexes (rechercher les rôles d'un utilisateur), vous ne profitez pas de ce que votre stockage de données fait de mieux.

Mon dernier argument contre cela serait la simplicité pour les autres développeurs. Vous avez des utilisateurs, des rôles et des affectations. C'est un ensemble de relations plusieurs-à-plusieurs (car il y a plus d'une relation) qui est si commun qu'il devrait être facile à gérer. C'est juste des trucs CRUD.

38
JeffO

Vous avez déjà nommé les avantages et les inconvénients pertinents:

  • Les champs de bits économisent de l'espace.
  • Ils stockent les données dans l'enregistrement lui-même, vous n'avez donc pas besoin de JOIN pour les trouver. (Mais les champs d'indicateur individuels de l'enregistrement feraient de même.)
  • Ils sont mal lisibles si vous souhaitez travailler de manière productive avec une sortie SQL brute.

Décider quoi faire nécessite plus d'informations:

  • À quel point l'espace disque est-il limité pour votre cas d'utilisation?
  • Lisez-vous réellement les rôles des utilisateurs si souvent que le temps de les rejoindre est un goulot d'étranglement?
  • Are allez-vous lire la sortie SQL et prendre des décisions en fonction de cela - ou un enregistrement de base de données illisible est-il immatériel, tout comme ce fait que le code machine de votre système est illisible?

Donc, ce que vous avez à faire est de rassembler les facteurs de risque, puis poids eux, pour voir si les avantages l'emportent sur les inconvénients.

24
Kilian Foth

Si vous êtes vraiment, vraiment , vraiment à court d'espace disque, alors vous pourrait considérer les bitmaps pour les autorisations des utilisateurs. Si les performances vous inquiètent, oubliez-les complètement, car les séparer sera en fait plus lent. Vous ne pouvez pas indexer un champ bitmap de manière significative, ce qui entraîne des analyses de table de base de données, qui sont [presque] toujours un tueur de performances.

Sauf si vous êtes Amazon ou Netflix, la quantité de données impliquées dans les autorisations utilisateur sera négligeable par rapport à tout ce que vous détenez.

Tout SGBD sérieux peut gérer cette "jointure supplémentaire" sans même clignoter.

18
Phill W.

À l'époque où le stockage était coûteux, l'avantage des masques à mors était qu'ils avaient économisé de l'espace. À l'époque du Big Data, ce n'était plus le problème.

Prenons l'exemple que vous citez - avoir des rôles stockés sous forme de masque de bits serait une sorte d'odeur de code du point de vue de la conception d'une base de données car cela violerait première forme normale . En ce sens, ils sont un anti-modèle.

Cela étant dit, il n'est pas nécessaire que ce soit l'un ou l'autre. Vous pouvez stocker les données sous forme de masque de bits, puis avoir une vue qui peut extraire les rôles d'utilisateur à la volée. Vous auriez alors également l'avantage de vérifier en un coup d'œil quels utilisateurs avaient les mêmes rôles.

8
Robbie Dee

Le seul avantage de l'utilisation des masques de bits est que la signification des champs de bits n'est pas statique. Les tables relationnelles ne fonctionnent bien que si vous savez à l'avance ce que chaque champ est sur un enregistrement: vous devez identifier les champs dans le CREATE TABLE Instruction DDL après tout.

Si la signification de chaque champ de bits est configurable au moment de l'exécution, ou autrement inconnue à l'avance, alors est logique de stocker les booléens sous forme de champ de bits. Même alors, il est possible de définir une table avec des champs arbitraires: field_1, field_2, etc. Cela vous donne une conception relationnelle plus nette, bien que toujours pas idéale. Que ce soit préférentiel à un champ de bits est en grande partie une question d'opinion, car aucune des solutions n'est idéale.

Si vous savez ce que les bits représentent pendant le développement, créez des champs pour chaque bit et donnez-leur des noms significatifs .

Faites juste attention à effet de plateforme interne . Si vous finissez par définir des champs arbitraires mais bien typés, c'est une chose, mais si vous allez trop loin, vous réinventerez une base de données relationnelle ... à l'intérieur d'une base de données relationnelle.

2
user22815

Je suis ambivalent au sujet des bitmasks. Je trouve que la plupart de leurs détracteurs ne comprennent pas le binaire et l'hexadécimal. Pour plus de clarté, utilisez de bons mnémoniques.

Un avantage non mentionné ci-dessus est la possibilité d'ajouter une nouvelle signification aux masques de bits sans l'ajout potentiellement long d'une nouvelle colonne. Nos concepteurs de base de données (qui m'ont précédé) les ont dans un tableau qui obtient maintenant 5 millions de nouveaux enregistrements par jour. L'ajout d'une nouvelle colonne pour représenter un nouveau comportement prendrait beaucoup de temps, tandis que la définition d'un nouveau bit (nous en avons consommé 33 sur 64) ne nécessite aucune reconstruction de table.

Non, les masques de bits ne peuvent pas être indexés, mais la création de 33 index serait ridicule et ralentirait les insertions dans une analyse. Les recherches de table utilisent les dates et enregistrent les index "propriétaires", donc les index sur ce masque de bits, si possible, ne seront jamais utilisés.

2
G B

Si le but est juste d'économiser de l'espace disque, je pense que c'est une mauvaise idée:

  • regardez le coût du GB aujourd'hui,
  • le comparer au coût du temps de ceux qui rédigent des rapports et des requêtes et doivent comprendre ce qui se trouve sur le terrain, et comment traiter un bit spécifique, la comparaison coût/avantage pourrait se terminer du mauvais côté.
  • si vous travaillez avec une base de données SQL, les opérations supplémentaires d'accès aux bits requises dans de nombreuses requêtes peuvent également consommer plus de temps de calcul que nécessaire

Cependant, il existe certains cas, qui peuvent justifier l'utilisation de champs de bits:

  • si vos bits représentent un ensemble complexe de drapeaux que vous gérez toujours ensemble dans leur ensemble,
  • encore plus si vous devez appliquer des algorithmes de correspondance de motifs sur ces ensembles,
  • et surtout si ces données ne figurent pas parmi les critères de sélection les plus fréquemment utilisés.
1
Christophe