2012-02-10 3 views
5

У меня есть следующие таблицы:Битовые операции в Postgres

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

и

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 

Я хотел бы запросить в настоящее время:

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 

Каков наилучший показатель для таблиц types и vendors в postgres? У меня могут быть миллионы строк в поставщиках. Более того, каковы компромиссы с использованием этого побитового метода по сравнению с отношением Many To Many с использованием третьей таблицы? Что лучше?

+0

Я думаю, вы имеете в виду «type & 7 = 0», если вы используете «type & 7> 0», вы вернете любой элемент, который соответствует «A», «B» или «C», поскольку совпадение любого бита будет в результате получается ответ больше 0. (Алекс, Боб, Дэвид, Эд, Цель, Генри, Ирис, Джек) Создание «type & 7 = 0» приводит только к тем элементам, которые соответствуют всем трем битам. (Эд, Ирис, Джек) –

ответ

8

Использование можно использовать частные индексы, чтобы обойти тот факт, что «&» не является индексируемой оператор (AFAIK):

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

Конечно, вам необходимо добавить новый индекс каждый раз, когда вы добавьте новый тип. Это одна из причин расширения данных в таблицу ассоциаций, которая затем может быть правильно проиндексирована. Вы всегда можете писать триггеры для поддержки таблицы битовой маски дополнительно, но используйте таблицу «многие-ко-многим», чтобы фактически поддерживать данные в обычном режиме, поскольку это будет намного яснее.

Если ваша оценка масштабирования и производительности означает «У меня могут быть миллионы строк», вы не сделали достаточно, чтобы начать эту оптимизацию. Сначала создайте правильно структурированную четкую модель, оптимизируйте ее позже на основе реальных статистических данных о том, как она выполняется.

Смежные вопросы