Wo finde ich das Kapitel über „Was mich in­ter­es­siert“ in einem Buch? Wohin geht die Be­stel­lung von Marta Mus­ter­mann? Wo gibt es die Uhr mit dem braunen Le­der­arm­band zu kaufen? – Was haben diese drei Sätze gemeinsam? Die erste Ge­mein­sam­keit ist, dass es Fragen sind. Die zweite Ge­mein­sam­keit besteht darin, dass es sich um Fragen nach einem Ort – also „Wo(hin)?“ – handelt. Und drittens setzen alle drei Fra­ge­sät­ze voraus, dass es das Gesuchte auch gibt. Dieses Ge­dan­ken­mo­dell lässt sich recht einfach auf die Welt der Da­ten­ban­ken über­tra­gen.

Stellen Sie sich einen On­line­shop mit tausenden Artikeln und Kunden vor. Alle diese Daten werden in Da­ten­ban­ken ge­spei­chert. Der Kunde sucht in der Datenbank nach einem be­stimm­ten Artikel und bestellt, der Versender ordnet per Datenbank den be­stell­ten Artikel dem Besteller mit seinen Adress­da­ten zu. Das hat diverse Such- und Sor­tier­auf­ga­ben, Einfüge- und Lösch­vor­gän­ge während des Be­stell­vor­gangs zur Folge. Um diese Aufgaben ef­fi­zi­en­ter zu be­wäl­ti­gen, werden zu­sam­men­ge­hö­ri­ge große Da­ten­men­gen an einer Adress­po­si­ti­on in der Datenbank zu­sam­men­ge­fasst. Diese Position wird mit Hash­wer­ten berechnet und besteht dann aus einer Tabelle mit Zahlen-Buch­sta­ben-Kom­bi­na­tio­nen stets gleicher Länge. Unser Ratgeber macht Sie mit den Grund­sät­zen der Ver­wen­dung dieser Hash­ta­bel­len vertraut.

Was ist das Prinzip einer Hash­ta­bel­le?

Aus den In­for­ma­tio­nen eines Da­ten­sat­zes wird zuerst ein Hashwert berechnet. Die Hashwerte aller Da­ten­sät­ze einer Datenbank befinden sich in der Hash­ta­bel­le. Eine weitere ma­the­ma­ti­sche Operation errechnet aus dem Hashwert den Spei­cher­ort dieser In­for­ma­tio­nen in der Datenbank. Gibt der Nutzer nun einen Such­be­griff ein, wird auch dieser gehasht. Es wird daher nicht mehr nach der „Arm­band­uhr mit dem braunen Le­der­arm­band“ gesucht, sondern nach einer Über­ein­stim­mung des ur­sprüng­lich gehashten Werts für den Artikel mit dem Hashwert des gerade ver­wen­de­ten Such­be­griffs, also nach einer Über­ein­stim­mung zweier Zahlen-Buch­sta­ben-Kom­bi­na­tio­nen. Dies wird für ganz un­ter­schied­li­che Lösungen angewandt.

Si­cher­heit mit Hash­wer­ten

Eine Hash­ta­bel­le entsteht nach der Zuordnung von au­to­ma­tisch ge­ne­rier­ten Hashes zu be­lie­bi­gen Begriffen. Die dazu ein­ge­setz­te Hash­funk­ti­on erzeugt einen Hash, also eine Zei­chen­fol­ge immer gleicher Länge. Die Länge der Zei­chen­fol­ge und die darin ent­hal­te­nen Zeichen werden durch die ver­wen­de­te Hash­me­tho­de fest­ge­legt. Das wird bei­spiels­wei­se dazu benutzt, Zu­gangs­da­ten sicherer vor Angriffen zu machen.

Beim An­mel­de­ver­such im Beispiel der WordPress-Datenbank wird das ein­ge­ge­be­ne Passwort des Nutzers mit dem gleichen Verfahren in einen Hashwert um­ge­rech­net, dann mit dem in der Datenbank vor­han­de­nen Eintrag im Da­ten­bank­feld „user_pass“ ver­gli­chen. Bei Über­ein­stim­mung der beiden 34 Zeichen langen Hashes wird der Zugang gewährt. Das Rückwärts-Auslesen des Hashwerts zu einem Passwort ist nicht möglich. Das ist ein Qua­li­täts­merk­mal einer Hash­funk­ti­on.

Bei Ein­dring­ver­su­chen wie dem Brute-Force-Angriff muss diese Zei­chen­ket­te mit allen zu­ge­las­se­nen Zeichen so lange durch­lau­fen werden, bis eine Über­ein­stim­mung gefunden ist. Wenn die ver­wen­de­te Hash­funk­ti­on bekannt ist, würde ein Angreifer bei der Ver­wen­dung von Groß- und Klein­buch­sta­ben sowie Ziffern in einem 10 Zeichen langen Passwort exakt 839.299.365.868.340.200 Versuche zum Ermitteln einer Über­ein­stim­mung benötigen.

Schneller in Da­ten­ban­ken unterwegs

Für Da­ten­ban­ken werden Hash­ta­bel­len genutzt, um Such­vor­gän­ge sowie das Eintragen oder Löschen von Da­ten­sät­zen zu be­schleu­ni­gen. Wenn man zum Beispiel eine Datenbank aller Mit­ar­bei­ter eines Un­ter­neh­mens nach einem Nachnamen durch­sucht, kann das sehr viel Zeit in Anspruch nehmen, weil jedes Da­ten­bank­feld nach­ein­an­der (se­quen­zi­ell) auf Über­ein­stim­mung durch­sucht wird. Wandelt man den Such­be­griff in einen Hashwert um und sucht damit in der Hash­ta­bel­le nach Über­ein­stim­mung, geht es in der Regel viel schneller.

Wie wird dies rea­li­siert? Jeder Datensatz bekommt eine ein­deu­ti­ge Adresse. Die Art dieser Adres­sie­rung ist innerhalb der Datenbank immer identisch (001, 002, 003 oder 00A1, 00A2, 00A3 usw.). Diese Adresse wird mithilfe der Hash­funk­ti­on berechnet.

Ein einfaches Beispiel: Eine Datenbank hat Platz für 11 Einträge, von Position 0 bis Position 10. Der Name „Lisa“ besteht aus vier ASCII-Zeichen mit den je­wei­li­gen ASCII-Codes: L ist 76, i ist 105, s ist 115 und a ist 97. Das können Sie in Windows mit dem Num­mern­feld selbst aus­pro­bie­ren: [Alt] + 0076 bei­spiels­wei­se ergibt „L“. Alle ASCII-Werte werden addiert und ergeben für „Lisa“ den Hashwert 393. Die Addition der ASCII-Werte ent­spricht hier nun einer Hash­funk­ti­on.

Dann wird eine Rest­wert­be­rech­nung mit Ganz­zah­len aus­ge­führt: 393 % 11 (Spei­cher­plät­ze) = 35, Rest 8 (das Pro­zent­zei­chen „%“ ist in vielen Pro­gram­mier­spra­chen der ma­the­ma­ti­sche Operator für die Rest­wert­be­rech­nung). Dieser Restwert bestimmt nun, an welcher Stelle der Datenbank – hier im Re­chen­bei­spiel also der Index Nummer 8 – Lisa und alle weiteren Angaben von ihr ge­spei­chert werden. Es ist leicht vor­zu­stel­len, dass bei dieser Art von Adres­sie­rung häufig gleiche Restwerte auftreten. Je mehr Spei­cher­plät­ze und je länger der benutzte Hashwert, desto geringer ist jedoch die Wahr­schein­lich­keit, dass eine solche Dopplung auftritt. Bei „Alis Meyer“ träte trotz „gleicher“ Buch­sta­ben eine ganz andere Po­si­tio­nie­rung auf, da das „A“ jetzt groß- und das „l“ jetzt klein­ge­schrie­ben ist.

In der Abbildung offenbart sich das Problem einer Dopplung: Ver­schie­de­ne Namen können durchaus gleiche Indizes bekommen. Das erzeugt die so­ge­nann­ten Kol­li­sio­nen (hellblaue Pfeile). Was „macht“ die Datenbank mit einem solchen „Unfall“? Sie legt den Datensatz an der nächst­mög­li­chen freien Stelle in der Datenbank ab. Wird nun im Beispiel nach „Berta Müller“ gesucht, beginnt die Suche nicht an Position 001, sondern der Such­zei­ger wird gleich zum Anfang auf Index-Position 003 gesetzt, was eine (geringe) Zeit­ver­kür­zung darstellt. Diese Methode wird als Hashing mit offener Adres­sie­rung be­zeich­net, in der dann linear gesucht wird.

Einen etwas anderen Weg be­schrei­tet die ver­ket­te­te Adres­sie­rung (chaining). Es wird kein neuer Datensatz „auf­ge­macht“, sondern nach dem ersten zu­tref­fen­den Eintrag wird der nächst­zu­tref­fen­de verkettet abgelegt. Damit wird der gesuchte Datensatz mit nur einem Such­auf­ruf gefunden, und zwar „hinter“ dem ersten Datensatz an der Spei­cher­po­si­ti­on. Ein Plus an Ver­ar­bei­tungs­ge­schwin­dig­keit ist die Folge.

Der Da­ten­zei­ger wird gleich zu Beginn der Suche nach „Berta Müller“ auf den aus der Hash­ta­bel­le er­rech­ne­ten Wert 003 gesetzt und hat dann hier nur noch einen ver­ket­te­ten Datensatz zu durch­su­chen. Somit lassen sich große Da­ten­men­gen eleganter „verpacken“ und schneller durch­su­chen.

Auch beim so­ge­nann­ten Caching wird dieses Prinzip verwendet, um einmal benutzte Daten schnell wieder zur Verfügung zu haben. Sie werden im Cache, dem Zwi­schen­spei­cher, abgelegt und bei Über­ein­stim­mung mit einem Tä­tig­keits­mus­ter von dort abgerufen. Die geschieht z. B. mit besuchten Webseiten, die beim erneuten Aufruf nicht komplett neu vom Server geladen werden müssen, sondern aus dem viel schnel­le­ren Cache abgerufen werden. Auch Cookies dienen als eine Art der ver­glei­chen­den Iden­ti­fi­ka­ti­on, wo der User schon im Web unterwegs war.

Welche Varianten des Hash­ver­fah­rens gibt es?

Das eben dar­ge­stell­te Hash­ver­fah­ren wird auch als offenes oder ex­ter­na­les Hashing be­zeich­net, bei dem in einem theo­re­tisch un­be­grenz­ten Spei­cher­raum Daten in ver­ket­te­ten Listen abgelegt werden können. So stehen zwar nicht mehr Schlüssel zur Verfügung, aber die Ver­ket­tung erlaubt die Be­wäl­ti­gung größerer Da­ten­men­gen. Das Wort „offen“ steht für die offene Adres­sie­rung.

Beim ge­schlos­se­nen Hashing ist die Anzahl der ver­füg­ba­ren Schlüssel durch die Kapazität der Tabelle begrenzt. Versucht man, mehr Daten zu speichern, entsteht ein so­ge­nann­ter Überlauf (Overflow). Beim erneuten Durchlauf durch die Tabelle wird sondiert, an welchen noch freien Po­si­tio­nen dort solche „Über­läu­fer“ platziert werden können.

Hinweis

Die Ver­wen­dung der Begriffe „offenes“ und „ge­schlos­se­nes“ Hashing ist nicht eindeutig geregelt. Sie werden in Pu­bli­ka­tio­nen zum Teil ent­ge­gen­ge­setzt verwendet. Es ist emp­feh­lens­wert, die jeweilige de­tail­lier­te Be­schrei­bung des Ver­fah­rens zu nutzen.

Das Kuckucks-Hashing dient ebenfalls der Ver­mei­dung von Kol­li­sio­nen in der Datenbank-Tabelle. Die Be­zeich­nung stammt vom Verhalten des Kuckucks, Eier anderer Vögel aus einem Nest zu entfernen, um dann sein eigenes darin abzulegen. So werden hier zwei Hash-Funk­tio­nen ein­ge­setzt, um zwei Spei­cher­or­te zu de­fi­nie­ren. Ist die erste Position schon besetzt, wird der dort vor­han­de­ne Schlüssel an eine neue Position versetzt, während der zweite erzeugte Schlüssel am ersten Spei­cher­ort platziert wird. Der Nachteil dieser Variante besteht darin, dass sich eine unendlich ab­lau­fen­de Such­schlei­fe bilden kann, sodass eine ein­ge­lei­te­te Routine wegen Zeit­über­schrei­tung ab­ge­bro­chen wird.

Zum Sondieren in der Datenbank gibt es ver­schie­de­ne Verfahren, die mit kom­pli­zier­ten ma­the­ma­ti­schen Formeln kon­stru­iert wurden, die sich als Pro­gramm­code auf einer Webseite bei­spiels­wei­se hinter dem schlich­ten Suchfeld mit der Lupe verbergen.

Da­ten­ban­ken werden in der Regel um­fang­rei­cher, der Da­ten­be­stand wächst mit großer Ge­schwin­dig­keit an. Das dy­na­mi­sche Hashing be­rück­sich­tigt das, in dem es zur Ver­mei­dung von Kol­li­sio­nen die Hash­ta­bel­le ver­grö­ßert. Das zieht jedoch den Umstand nach sich, dass sich auch die Hashwerte bereits ge­spei­cher­ter Daten verändern. Es wurden spezielle Hash­funk­tio­nen ent­wi­ckelt, die auch dieses Problem elegant lösen. Somit gibt es (zumindest theo­re­tisch) keine Grenze für die Da­ten­men­ge. Al­ler­dings sind die Such­durch­läu­fe dann weniger effizient.

Vor- und Nachteile von Hash­ta­bel­len

Der größte Vorteil des Einsatzes einer Hash­ta­bel­le ist das schnelle Suchen in sehr großen Da­ten­men­gen. Al­ler­dings stellt es den Ar­chi­tek­ten der Datenbank vor die Her­aus­for­de­rung, die benötigte Größe vorab gut ab­zu­schät­zen, um die Kol­li­si­ons­ge­fahr gering zu halten. Es können viele Da­ten­ty­pen verwendet werden, solange aus ihnen Hashwerte berechnet werden können.

Die Schwächen dieser Her­an­ge­hens­wei­se bestehen u. a. darin, dass die Da­ten­ban­ken durch eine Vielzahl von Kol­li­sio­nen re­gel­recht entarten können. Die Wahr­schein­lich­keit von Kol­li­sio­nen steigt mit der Da­ten­men­ge an. Eine große Zahl von Hash­funk­tio­nen gestattet es nicht, sich zum nächsten oder vor­he­ri­gen Datensatz zu bewegen.

Zum Hauptmenü