2012-02-02 10 views
6

Muszę zrobić zapytanie kwerendy w tabeli księgowania, w którym ustawiony jest określony bit liczby całkowitej. Liczba całkowita reprezentuje zestaw kategorii w masce bitowej: E.g.WYBIERZ wiersze mySQL, gdzie określony bit liczby całkowitej jest ustawiony

1 => health 
2 => marketing 
3 => personal 
4 => music 
5 => video 
6 => design 
7 => fashion 
8 => ...... 

przykład danych:

id | categories | title 
1 | 11   | bla bla 
2 | 48   | blabla, too 

muszę zapytanie mysql, który wybiera komentarze, które zostały oznaczone konkretnej kategorii. Powiedzmy „wszystkie komentarze wideo” Oznacza to muszę zestaw wyników księgowania gdzie 5th nieco kolumny catgories jest ustawiony (np 16,17,48 ....)

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

jakieś pomysły?

+1

Dlaczego nie tylko dodatkowa tabela pomiędzy: categories_postings? To byłoby bardziej przyszłościowe rozwiązanie, ponieważ wydaje się to zwykłą bazą danych wielu kategorii? –

+1

Zgadzam się z Lucem, łatwiej będzie utrzymać dodatkową tabelę zwaną, powiedzmy, groups_groups, która będzie miała strukturę taką jak: id, category_group_name, health, marketing, personal, music ... i która będzie posiadać albo "0"/"1" w każdej kategorii, aby oznaczyć, czy ta kategoria należy do tej grupy. W ten sposób znacznie łatwiej będzie zsumować liczbę grup, które zawierają kategorię "zdrowie". – alfasin

+0

@Luc - oboje macie rację - faktem jest, że dane są publikowane przez zewnętrzną aplikację, gdzie nie mogę wprowadzać żadnych zmian. Wiele relacji byłoby najlepszym rozwiązaniem ... – derRobert

Odpowiedz

9

Można używać operatorów takich jak ten. Wideo (bit 5):

WHERE categories & 16 = 16 

Zastępca wartość 16 stosując następujące wartości dla każdego bitu:

1 = 1 
2 = 2 
3 = 4 
4 = 8 
5 = 16 
6 = 32 
7 = 64 
8 = 128 

to idzie od najmniej znaczącego bitu do najwyższego, który jest przeciwieństwem sposobu większość programistów myśleć. Zaczynają także od zera.

+0

Powyższe mapowania można uprościć jako: bitVal = 2^(i-1), gdzie i jest wartością indeksu po lewej stronie. Na przykład 16 = 2^(5-1). –

2

Jak o

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

Jeden problem z tym jest to, że prawdopodobnie nie trafi do indeksu, więc można uruchomić w kwestii perf jeśli jest duża ilość danych.

Niektóre bazy danych (takie jak PostgreSQL) umożliwiają zdefiniowanie indeksu takiego wyrażenia. Nie jestem pewien, czy mySQL ma tę funkcję. Jeśli jest to ważne, możesz rozważyć ich podział na oddzielne kolumny Boolean lub nową tabelę.

-1

SQL (nie tylko mySQL) nie nadaje się do operacji bitowych. Jeśli zrobisz bitowe I wymusisz skanowanie tabeli, ponieważ SQL nie będzie mógł używać żadnego indeksu i będzie musiał sprawdzać każdy wiersz po jednym.

Byłoby lepiej, gdyby utworzono oddzielną tabelę "Kategorie" i odpowiednio zindeksowano wiele tablic PostingCategories do połączenia dwóch.

UPDATE

Dla ludzi, twierdząc, że pola bitmapy nie są problemem, warto sprawdzić Joe Celko na BIT of a Problem. W dolnej części artykułu znajduje się lista poważnych problemów spowodowanych przez mapy bitowe.

Odnośnie komentarza, że ​​oświadczenie koc nie może być prawda, Nota nr 10 - rozkłada 1nF więc tak, pola rastrowe są złe:

  1. Dane są nieczytelne. ...
  2. Ograniczenia to b #### do napisania ....
  3. Ograniczasz się do dwóch wartości na pole. To bardzo restrykcyjne; nawet kod seksu ISO nie mieści się w takiej kolumnie ...
  4. Nie ma elementu tymczasowego do maski bitowej (lub do flag jednobitowych). Na przykład flaga "is_legal_adult_flg" ... DATA dla daty urodzenia (tylko 3 bajty) będzie zawierała kompletny fakt i obliczmy to, co musimy wiedzieć; zawsze też będzie to poprawne. ...
  5. Dowiesz się, że używanie flag będzie miało tendencję do dzielenia statusu jednostki na wiele tabel ...
  6. Flagi bitowe zachęcają do nadmiarowości. W systemie, który właśnie wspomniałem, mieliśmy "is_active_flg" i "is_completed_flg" w tej samej tabeli. Zakończona aukcja nie jest aktywna i jest wersetem. To jest ten sam fakt w dwóch flagach. Psychologia ludzka (i język angielski) woli słyszeć afirmatywne sformułowanie (pamiętajcie o starej pieśni "Tak, dziś nie mamy bananów!"?). Wszystkie te znaczniki bitów i sprawdzanie poprawności sekwencji są zastępowane przez dwa zestawy tabel przejść stanu, jeden dla licytacji i jeden dla wysyłek. Szczegółowe informacje na temat ograniczeń przejścia stanu. Historia każdej aukcji jest teraz w jednym miejscu i musi być zgodna z regułami biznesowymi.
  7. Zanim zdemontujesz kolumnę z bitową maską i wyrzucisz pola, których nie potrzebujesz, wydajność nie poprawi się w porównaniu z prostszymi typami danych.
  8. Grupowanie i zamawianie na poszczególnych polach to prawdziwy ból. Spróbuj.
  9. Musisz zindeksować całą kolumnę, więc jeśli nie powinieneś mieć szczęścia i mieć je we właściwej kolejności, utkniesz przy skanowaniu tabeli.
  10. Ponieważ maska ​​bitowa nie znajduje się w pierwszej normalnej formie (1NF), masz wszystkie anomalie, których chcieliśmy uniknąć w RDBMS.

Dodałbym również, co z NULL-y? A co z brakującymi flagami? Co jeśli coś nie jest ani prawdziwe, ani fałszywe?

Wreszcie, w odniesieniu do żądania kompresji, większość baz danych spakowuje pola bitów do bajtów i intów wewnętrznie. Pole bitmapy nie oferuje w tym przypadku żadnego rodzaju kompresji. Inne bazy danych (np. PostgreSQL) mają faktycznie typ Boolean, który może być prawdziwy/fałszywy/nieznany. Może to zająć 1 bajt, ale to , a nie dużo miejsca i przejrzysta kompresja jest dostępna, jeśli tabela staje się zbyt duża.

W rzeczywistości, jeśli tabela staje się duża, pola bitmapowe stają się znacznie poważniejsze. Zapisanie kilku MB w tabeli GB nie przynosi korzyści, jeśli jesteś zmuszony do korzystania ze skanowania tabeli lub jeśli utracisz możliwość grupowania

+0

Jest to zbyt wiele instrukcji zbiorczej, aby być dokładnym. To prawda, że ​​nie będzie można wykonywać skanów indeksu w polach bitowych, jednak często mogą się przydać i prowadzić do znacznego zmniejszenia rozmiaru pamięci lub przyspieszenia zapytania w zależności od tego, co zamierzasz. – delrox

+1

Jeśli wyszukiwanie wykorzystuje jedynie pole bitmapowe dla "ostatniej mili" - innymi słowy, zawęziło znacznie większe wyszukiwanie do kilkuset rekordów przy użyciu innych pól/indeksów - wtedy nie ma zbyt wiele kwestii perfekcyjnej, którą należy się zająć. W przypadku silnych statycznych zestawów danych, pola bitmapowe są, jak wspominali inni, przyjemną formą kompresji danych. (Nie mamy zamiaru dodawać nowego dnia tygodnia ani nowych godzin w ciągu dnia w najbliższym czasie, na przykład ...) – Techmag

+1

@Techmag faktycznie, nie. DBA zazwyczaj nienawidzą pól bitmapowych, ponieważ powodują one * LICZENIE * problemów, a wydajność jednego z nich. Sprawiają, że dane stają się nieczytelne, uniemożliwiają użycie ograniczeń i więcej. Sprawdź Joe Byczyna [BIT of a Problem] (https://www.simple-talk.com/sql/t-sql-programming/bit-of-a-problem/). To, co nazywacie kompresją, zwłaszcza w dniach, zostanie zastąpione prostym typem lub wartością wyliczeniową. W rzeczywistości można by spierać się o kompresję * tylko *, jeśli można użyć wszystkich bitów w polu podkładu. W przeciwnym razie byłbyś marnowany, np. 7 bitów z 16-bitowej granicy –