2009-02-13 5 views
1

Supposons que vous disposiez d'un long tableau de caractères 1 ou 0, un peu comme un bitvector, mais dans une colonne de base de données. Comment demanderiez-vous de savoir quelles valeurs sont définies/non définies? Supposons que vous ayez besoin de savoir si le char 500 et le char 1500 sont «vrais» ou non.Comment interroger un tableau de caractères 1 et 0 à partir d'une base de données?

+0

sont de 500 et 1500 seulement arbitraire positions ou interrogez-vous exactement ces deux encore et encore? – VolkerK

+0

Totalement arbitraire, la requête pourrait être quelque chose d'horrible comme 500,551,1502,234,1001,2035 par exemple –

Répondre

6
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 devient lent très rapidement. Editer: Sur SQL Server au moins, toutes les fonctions de chaîne intégrées sont deterministic. Cela signifie que vous pouvez étudier la possibilité de créer des colonnes calculées à partir des résultats SUBSTRING() pour l'ensemble de la valeur combinée, putting an index on each of them. Les insertions seront plus lentes, la taille de la table augmentera, mais les recherches seront vraiment rapides.

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

Edit # 2: Les limits for SQL Server sont:

  • 1.024 colonnes par table normale
  • 30.000 colonnes par "large" Table
3

En MySQL, en utilisant quelque chose comme substring

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 interrogeable

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; 

consomme évidemment plus de stockage, mais devrait être plus rapide pour les opérations de la requête en tant l'index sera utilisé.

2

Je convertirais la colonne en plusieurs colonnes de bits et réécrirais le code pertinent - Les masques bit sont tellement 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" 
1
select substring(your_col, 500,1) as char500, 
substring(your_col, 1500,1) as char1500 from your_table; 
Questions connexes