2012-02-10 14 views
5

Ho le seguenti tabelle:operazioni bit per bit in Postgres

types | id | name 
------+----+---------- 
     1 | A 
     2 | B 
     4 | C 
     8 | D 
     16| E 
     32| F 

e

vendors | id | name  | type 
--------+----+----------+----- 
      1 | Alex  | 2  //type B only 
      2 | Bob  | 5  //A,C 
      3 | Cheryl | 32 //F 
      4 | David | 43 //F,D,A,B 
      5 | Ed  | 15 //A,B,C,D 
      6 | Felix | 8  //D 
      7 | Gopal | 4  //C 
      8 | Herry | 9  //A,D 
      9 | Iris  | 7  //A,B,C 
      10| Jack  | 23 //A,B,C,E 

Vorrei interrogare ora:

select id, name from vendors where type & 16 >0 //should return Jack as he is type E 
select id, name from vendors where type & 7 >0 //should return Ed, Iris, Jack 
select id, name from vendors where type & 8 >0 //should return David, Ed, Felix, Herry 

Qual è il miglior indice possibile per le tabelle types e vendors in postgres? Potrei avere milioni di righe nei venditori. Inoltre, quali sono i compromessi nell'usare questo metodo bit a bit rispetto alla relazione Many To Many usando una terza tabella? Che è migliore?

+0

Penso che tu intenda 'digita & 7 = 0', se usi 'tipo & 7> 0' restituirai qualsiasi elemento che corrisponda a 'A', 'B' o 'C', poiché la corrispondenza con qualsiasi bit risultato in una risposta maggiore di 0. (Alex, Bob, David, Ed, Obiettivo, Henry, Iris, Jack) Se si esegue "type & 7 = 0", si ottengono solo quegli elementi che corrispondono a tutti e tre i bit. (Ed, Iris, Jack) –

risposta

8

Usa possono usare indici parziali per aggirare il fatto che "&" non è un operatore indicizzabile (afaik):

CREATE INDEX vendors_typeA ON vendors(id) WHERE (type & 2) > 0; 
CREATE INDEX vendors_typeB ON vendors(id) WHERE (type & 4) > 0; 

Naturalmente, è necessario aggiungere un nuovo indice ogni volta che si aggiungi un nuovo tipo. Quale è uno dei motivi per espandere i dati in una tabella di associazione che può quindi essere indicizzata correttamente. È sempre possibile scrivere trigger per mantenere una tabella di maschera di bit in aggiunta, ma utilizzare la tabella many-to-many per mantenere i dati normalmente, in quanto sarà molto più chiara.

Se l'intera valutazione del ridimensionamento e delle prestazioni è dire "potrei avere milioni di righe", non hai fatto abbastanza per iniziare a fare questo tipo di ottimizzazione. Creare innanzitutto un modello chiaro adeguatamente strutturato, ottimizzarlo in seguito sulla base di statistiche reali su come funziona.

Problemi correlati