Comment voulez-vous interroger un tableau de 1 et de 0 caractères d'une base de données?

StackOverflow https://stackoverflow.com/questions/545320

  •  23-08-2019
  •  | 
  •  

Question

Supposons que vous aviez une longue série de caractères qui sont soit 1 ou 0, un peu comme un vecteur de bits, mais sur une colonne de base de données. Comment voulez-vous interroger pour savoir quelles valeurs sont définies / aucun jeu? Dites que vous devez savoir si le charbon 500 et 1500 sont ombles « true » ou non.

Était-ce utile?

La solution

SELECT
  Id
FROM
  BitVectorTable
WHERE
  SUBSTRING(BitVector, 500, 1) = '1'
  AND SUBSTRING(BitVector, 1000, 1) = '1'

Aucun indice ne peut être utilisé pour ce type de requête, cependant. Lorsque vous avez plusieurs lignes, cela se lent très rapidement.

Edit: Sur SQL Server au moins, toutes les fonctions de chaîne intégrées sont déterministe. Cela signifie que vous pouvez regarder dans la possibilité de faire des colonnes calculées en fonction des résultats SUBSTRING () pour la valeur totale combinée, mettre un index sur chacun d'eux . Les inserts seront plus lents, la taille de la table augmentera, mais les recherches sera très rapide.

SELECT
  Id
FROM
  BitVectorTable
WHERE
  BitVector_0500 = '1'
  AND BitVector_1000 = '1'

Edit # 2: pour SQL Server sont:

  • 1.024 colonnes par table normale
  • colonnes par table 30000 "large"

Autres conseils

En MySQL, quelque chose en utilisant sous-chaîne comme

select foo from bar 
where substring(col, 500,1)='1' and substring(col, 1500,1)='1';

Ce sera assez inefficace si, vous voudrez peut-être repenser votre schéma. Par exemple, vous pouvez stocker chaque bit séparément à l'espace compromis entre la vitesse ...

create table foo
(
   id int not null,
   bar varchar(128),
   primary key(id)
);

create table foobit
(
   int foo_id int not null,
   int idx int not null,
   value tinyint not null,

   primary key(foo_id,idx),
   index(idx,value)
);

Ce qui serait interrogé

   select foo.bar from foo
   inner join foobit as bit500
      on(foo.id=bit500.foo_id and bit500.idx=500)
   inner join foobit as bit1500
      on(foo.id=bit1500.foo_id and bit1500.idx=1500)
   where
      bit500.value=1 and bit1500.value=1;

Il est évident que plus de stockage consomme, mais devrait être plus rapide pour les opérations de requête comme un index sera utilisé.

Je convertir la colonne à plusieurs bits colonnes et réécrire le code correspondant - masques binaires sont beaucoup plus rapides que les comparaisons de chaînes. Mais si vous ne pouvez pas faire cela, vous devez utiliser des fonctions spécifiques db. Les expressions régulières pourraient être une option

-- Flavor: MySql
SELECT * FROM table WHERE column REGEXP "^.{499}1.{999}1"
select substring(your_col, 500,1) as char500,
substring(your_col, 1500,1) as char1500 from your_table;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top