Bitvektor index
Bitvektornak nevezünk egy hosszú (ahol a sorok száma) nullákból és egyesekből álló sorozatot. Egy bitvektor az tábla egy oszlopának értékéhez tartozik, -edik bitje pontosan akkor , ha az adott -edik sor adott oszlopának értéke .
Tekintsük a következő táblát:
Neptun | Kar | Felvétel éve |
---|---|---|
ABC123 | IK | 2018 |
XYZ789 | TTK | 2019 |
ASD135 | IK | 2020 |
GOT999 | IK | 2019 |
A tábla Kar
oszlopában szereplő értékek bitvektorai:
Kar="IK" |
---|
1 |
0 |
1 |
1 |
Kar="TTK" |
---|
0 |
1 |
0 |
0 |
Hasonlóan a Felvéltel éve
oszlopban szereplő értékek bitvektorai:
Felvétel="2018" |
---|
1 |
0 |
0 |
0 |
Felvétel="2019" |
---|
0 |
1 |
0 |
1 |
Felvétel="2020" |
---|
0 |
0 |
1 |
0 |
A Neptun
oszlopra szándékosan nem csináltunk bitvektorokat, mivel az oszlop értékkészlete túl nagy
(sőt tudjuk, hogy minden érték egyedi), ezért nem lenne értelme ilyen jellegű indexet készíteni.
Mire jók a bitvektor indexek?
A bitvektor indexek célja a logikai összehasonlítások felgyorsítása. Tekintsük a következő példát:
SELECT * FROM HALLGATOK WHERE KAR="IK" AND FELVÉTEL_ÉVE IN (2018, 2019);
Ekkor a lekérdezés eredményét megadó bitvektort, a következő módon tudjuk előállítani:
A Felvétel="2018"
és Felvétel="2019"
vektorokat bitenként összekapcsoljuk a logikai vagy művelettel, majd ezen
művelet eredményét és-el kapcsoljuk össze a Kar="IK"
vektorral.
Egy bitvektor tömörítés nélkül bájtot foglal, egy teljes oszlopra vonatkozó index pedig
bitből áll, ami jelentősen kevesebb tárhelyet (ezáltal kevesebb blokkolvasását) jelent, mivel index nélkül a konkrét értékeket is ki kellett volna olvasni.
A bitvektor indexek hátránya, hogy intervallum lekérdezések esetében nem hatékonyak.
Szakaszhossz kódolás
Vegyük észre, hogy bitvektoraink legtöbb esetben sok nullából és kevés egyesből állnak. Így bitvektorainkat akar eltárolhatnánk úgy is, hogy a nullákból álló szakaszok hosszait tároljuk el.
Kódolás
Legyen . Végigiterálunk a vektoron:
- Amikor az adott bit 0 megnöveljük -t.
- Amikor az adott bit 1 az változót bináris számmá alakítjuk:
- Legyen az szám bináris alakjának hossza.
- Lekódoljuk -t unárisan, ez azt jeleneti, hogy egyest és 1 db nullást kódolunk.
- A lekódolt -hez hozzáfűzzük bináris alakját.
- A szakaszt lekódoltuk, visszaállítjuk -t nullára.
Ha a bitvektor egy 1-es bittel kezdődik először 0 db nullást kell lekódolnunk, melynek kódja 00 lesz. (0 kettes számrendszerben 0, hossza 1, ami unárisan 0, melyeket összefűzve 00-t kapunk.)
Ha a bitvektor 0-ás bittel ér véget, ez eddigi szakasz hossza nem kerül lekódolásra. Mivel ismerjük a tábla sorainak számát ezért ezzel nem történik információvesztés.
Legyen a bitvektor .
Az első egyesig 13 nullán iteráltunk keresztül ezért , ami binárisan 1101, melynek hossza 4. Unárisan lekódolva négyet 1110 adódik. Így a bitvektor tömörített változata: .
Dekódolás
Legyen . Végigiterálunk a kódolt vektoron:
- Ha a bit 1, megnöveljük értékét eggyel.
- Ha a bit 0, akkor végetért az unáris hosszjelelő szakasz:
- Ekkor a következő biten van tárolva a nullák száma
- Kiolvassuk a következő bitet és visszaalakítjuk tízes számrendszerbe, jelöljük ezt a számot -vel.
- A kimenethez hozzáfűzünk db nullást és egy darab egyest.
Alakítsuk vissza az előző példában szereplő bitvektort (11101101):
Az első nulláig 3 egyesen iteráltunk végig, így tudjuk, hogy a szakaszhossz a következő 4 biten van tárolva. Ez a 1101 kettes számrendszerbeli szám, ami tízes számrendszerben 13. Így tehát 13 db nullást és 1 db egyest fejtünk vissza.
Bonyolultabb példa
Tömörítsük a (23, 7 és 1 db nulla) bitvektort!
Nullák | Binárisan | Hossz | Unáris hossz | Kód |
---|---|---|---|---|
23 | 5 | 11110 | 1111010111 | |
7 | 3 | 110 | 110111 | |
1 | 1 | 1 | 0 | 01 |
Így bitvektor: .
Fejtsük vissza a tömörített bitvektort!
Unáris Szakasz | Hossz | Kódolt szám | Eredeti vektorrész | Maradék |
---|---|---|---|---|
11110 | 5 | 21db nullás és 1 db egyes | 001011 | |
0 | 1 | 1db egyes | 1011 | |
10 | 2 | 3db nullás és 1 db egyes | - |
Így a tömörítetlen vektor: .