11
votes

MySQL Sélectionnez des lignes où un bit spécifique d'un entier est défini

Je dois faire une requête SELECT dans une table d'affichage dans laquelle un bit spécifique d'un entier est défini. L'entier représente un ensemble de catégories dans un masque bitmas: Par exemple xxx pré>

Exemple de données: strong> p> xxx pré>

J'ai besoin d'une requête MySQL qui sélectionne des affichages, qui sont marqués avec une catégorie spécifique. Disons "toutes les publications vidéo" Cela signifie que j'ai besoin d'un ensemble de résultats d'affichage dans lequel le 5ème bit de la colonne Catgories est défini (par exemple 16,17,48 ....) p>

SELECT * FROM postings WHERE ....????


4 commentaires

Pourquoi pas seulement une table supplémentaire entre: catégories_postings? Ce serait une solution de preuve plus future, car cela ne semble que une base de données standard de catégories multiples?


Je suis d'accord avec Luc, ce sera plus facile de maintenir une table supplémentaire appelée, disons, catégories_groups, qui aura une structure comme: Id, catégorie_group_name, santé, marketing, personnel, musique ... et qui tiendra " 0 "/" 1 "sous chaque catégorie pour marquer si cette catégorie appartient à ce groupe. De cette façon, il sera également beaucoup plus facile de résumer le nombre de groupes incluant la catégorie «Santé».


@LUC - Vous avez tous les deux raison - le fait est que les données sont publiées par une application externe où je ne peux apporter aucune modification. Une relation de nombreuses nombreuses solutions serait la meilleure solution ....


Lorsque cela fonctionne pour vous, je considérerais même l'étape d'analyse et de structuration des données dans un meilleur modèle de données si possible avant de travailler avec elle.


3 Réponses :


4
votes

Que diriez-vous de

SELECT * FROM postings WHERE (categories & 16) > 0; -- 16 is 5th bit over


0 commentaires

18
votes

Vous pouvez utiliser Opérateurs Bitwise comme celui-ci. Pour la vidéo (bit 5): xxx

substitut la valeur 16 à l'aide des valeurs suivantes pour chaque bit: xxx < P> Cela va d'un peu significatif à la plus haute, ce qui est opposé à la façon dont la plupart des programmeurs pensent. Ils commencent également à zéro.


2 commentaires

Les mappages ci-dessus peuvent être simplifiés comme suit: Bitval = 2 ^ (I-1), où je suis la valeur d'index à gauche. Donc, par exemple, 16 = 2 ^ (5-1).


Y a-t-il une différence entre où les catégories et 16 = 16 et où les catégories et 16> 0 ? Si je suis correct, l'opérateur bitwise doit renvoyer 0 si le bit n'est pas défini.



0
votes

SQL (non seulement MySQL) ne convient pas aux opérations bitwises. Si vous faites un bitwise et que vous forcerez une analyse de table comme SQL ne pourra utiliser aucun index et devra vérifier chaque ligne une à la fois.

Il serait préférable que vous ayez créé une table "catégories" distincte et une table de post-à-plusieurs dimensions correctement indexée pour connecter les deux.

mise à jour

Pour les personnes insistant pour que les champs bitmap ne soient pas un problème, il aide à vérifier Joe Celko's un peu d'un problème . Au bas de l'article se trouve une liste de problèmes graves causés par des bitmaps.

En ce qui concerne le commentaire qu'une déclaration de couverture ne peut pas avoir raison, note n ° 10 - il casse 1nf donc oui, les champs bitmap sont mauvais:

  1. Les données sont illisibles. ...
  2. Les contraintes sont une B #### pour écrire ....
  3. Vous êtes limité à deux valeurs par champ. C'est très restrictif; Même le code du sexe ISO ne peut pas entrer dans une telle colonne ...
  4. Il n'y a pas d'élément temporel au masque de bits (ni aux drapeaux de bits). Par exemple, un drapeau "is_legal_adult_flg" ... une date de la date de naissance (seulement 3 octets) tiendra des choses complètes et que nous consacrons ce que nous devons savoir; Ce serait toujours correct aussi. ...
  5. Vous découvrirez que l'utilisation des drapeaux aura tendance à scinder le statut d'une entité sur plusieurs tables ...
  6. Les drapeaux de bits invitent la redondance. Dans le système, je viens de mentionner, nous avions "is_active_flg" et "is_completed_flg" dans la même table. Une vente aux enchères terminée n'est pas active et vice-vers. C'est le même fait dans deux drapeaux. La psychologie humaine (et la langue anglaise) préfère entendre un libellé affirmatif (souvenez-vous de l'ancienne chanson "Oui, nous n'avons pas de bananes aujourd'hui!"?). Tous ces drapeaux de bits et la validation de séquence sont remplacés par deux ensembles de tables de transition d'état, une pour les offres et une pour les envois. Pour plus de détails sur les contraintes de transition de l'état. L'histoire de chaque vente aux enchères est maintenant à un endroit et doit suivre les règles de l'entreprise.
  7. Au moment où vous désassemblez une colonne de masque de bits, et jetez les champs que vous n'avez pas besoin de performance ne sera pas amélioré sur des types de données plus simples.
  8. Le regroupement et la commande sur les champs individuels est une vraie douleur. Essayez-le.
  9. Vous devez indexer la colonne entière, alors à moins que vous ne les ai pas de chance et que vous les avez dans le bon ordre, vous êtes coincé avec des analyses de table.
  10. Puisque un masque de bits n'est pas sur la première forme normale (1NF), vous avez toutes les anomalies que nous voulions éviter dans les SGBR.

    J'ajouterais aussi, qu'en est-il des nulls? Qu'en est-il des les drapeaux manquants? Et si quelque chose n'est ni vrai ni faux?

    Enfin, en ce qui concerne la réclamation de compression, la plupart des bases de données emballent des champs de bits dans des octets et des Ints en interne. Le champ bitmap n'offre aucun type de compression dans ce cas. D'autres bases de données (par exemple, PostgreSQL) ont en fait un type booléen qui peut être vrai / faux / inconnu. Il peut prendre 1 octet mais c'est pas beaucoup de stockage et de compression transparente est disponible si une table devient trop grande.

    En fait, si une table devient grande, les problèmes de champs bitmap deviennent beaucoup plus graves. Économiser quelques mbs dans une table GB n'est pas un gain si vous êtes obligé d'utiliser des analyses de table, ou si vous perdez la possibilité de grouper


9 commentaires

C'est trop d'une déclaration générale pour être exacte. Il est vrai que vous ne serez pas en mesure de faire des analyses indexées dans les champs Bitwise. Cependant, ils peuvent souvent être utiles et conduisent à une réduction massive de la taille du stockage ou de la compensation de requête en fonction de ce que vous allez.


Si votre recherche utilise uniquement le champ bitpepped pour le "dernier mile" - En d'autres termes, vous avez réduit une recherche beaucoup plus importante jusqu'à quelques centaines d'enregistrements en utilisant d'autres champs / index - alors il n'y a pas beaucoup de une question de perfs à préoccuper. Pour des jeux de données statiques puissants Les champs bitmapped sont, comme d'autres personnes ont mentionné, une belle forme de compression de données. (Nous n'allons pas ajouter un nouveau jour à la semaine ni aucune nouvelle heure dans une journée à tout moment bientôt, par exemple ...)


@Techmag en fait, non. Les dabas hainent généralement les champs bitmap parce qu'ils causent un lot de problèmes, la performance l'une d'elles. Ils rendent les données illisibles, empêchent l'utilisation de contraintes et plus encore. Vérifiez Joe Celko's BORG D'UN PROBLÈME . Ce que vous appelez la compression, surtout pendant des jours, serait remplacé par un type simple ou une valeur enum. En fait, vous pouvez discuter de la compression seulement si vous pouviez utiliser tous les bits sur le champ de support. Sinon, vous vous gastiriez, par exemple 7 bits d'un belding 16 bits


@Delrox en réalité, ce n'est pas une déclaration générale. Vérifiez l'article de Celko, mais le fait même que 1NF est cassé pendant que les données sont illisibles suffit à leur faire une mauvaise idée. Il n'y a pas de réduction de stockage non plus, à moins que votre base de données ne puisse pas gérer les champs mono-bits. La plupart des bases de données embalent réellement plusieurs bits en octets, intenses et longs interne.


@Delrox Comme vous allez lire dans l'article de Celko et mes modifications, les champs Bitmap ne fournissent ni compression ni prestations de performance. surtout dans des tables plus grandes.


@Delrox En fait, dans de très grandes tables que celles trouvées dans les entrepôts de données, les drapeaux sont stockés dans une table de dimension indésirable avec un seul champ par drapeau. Seul l'ID de la dimension est stocké dans la table des faits. C'est bien une meilleure compression que tout ce que vous pourriez atteindre avec un champ de bitmap


Les champs utilisés pour les opérations bits peuvent stocker plus de deux valeurs. Je me demande si vous confondez des bits avec des champs de bits (0 ou 1).


@Marcusadams Si je le faisais, je ne parlerais pas de drapeaux ou de pointer vers un article qui explique pourquoi le groupement de plusieurs drapeaux dans un seul champ est une mauvaise idée ou de parler de problèmes d'indexation.


@Marcusadams Vous référez-vous à que vous êtes limité à deux valeurs par champ fait référence à l'ensemble du champ? Il fait référence au champ bitmask . Vous ne pouvez pas avoir plus de deux valeurs dans ce cas, pas même une null.