Hash-Werte in MySQL / MariaDB platzschonend abspeichern

Datum

Jeder kennt das Standard-Verfahren, Hash-Werte, die z. B. zum Speichern von Passwörtern verwendet werden, als Datentyp CHAR oder gar VARCHAR abzuspeichern. Das ist in kleinen Tabellen auch nicht weiter dramatisch. Es zahlt sich jedoch bei großen Datenbanken aus, den Datentyp in MySQL / MariaDB zu ändern, in BINARY.

Als Beispiel möchte ich Whirlpool heranziehen:

echo -n 'Test123'>test && hashdeep -c whirlpool -s test | tail -n 1 | cut -d',' -f2 && rm test
6634b5f2750bff1f19d957b3cfae05277977caa2169e2b7fc220b5a3985cf863d355fc7fe3e1e5158c2e6fd9b356ed797fe59a04e666f08d51b8ef5d6357333c

Wir sehen, dass eine 128 Zeichen lange Kette entsteht. Immer. Bei jedem Datensatz. Das macht einen Speicherplatzbedarf von min. 128 Byte für jeden Datensatz. Da Hash-Werte idR. hexadezimale Darstellungen von Zahlenketten sind, lässt sich das optimieren, indem wir den Wert in der Datenbank umwandeln, in seine eigentlichen Byte. Also statt VARCHAR oder CHAR verwenden wir BINARY. Und das geht so:

CREATE TABLE t_user(
    id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
    login VARCHAR(24) NOT NULL,
    passwd BINARY(64) NOT NULL,
    passwd_txt CHAR(128) GENERATED ALWAYS AS (LOWER(HEX(passwd))) VIRTUAL
);

Und das Abspeichern / Einspielen von Datensätzen sieht dann so aus:

INSERT INTO t_user(login,passwd) VALUES('test',UNHEX('6634b5f2750bff1f19d957b3cfae05277977caa2169e2b7fc220b5a3985cf863d355fc7fe3e1e5158c2e6fd9b356ed797fe59a04e666f08d51b8ef5d6357333c'));

Hierbei schlagen wir gleich zwei Fliegen mit einer Klappe:

  1. Die Daten werden platzschonend abgespeichert und
  2. wir haben einen einfachen Weg, eine lesbare Form abzugreifen, zu vergleichen usw., mittels der virtuellen Spalte passwd_txt, die – da sie virtuell ist – selbst keinen Speicherplatz belegt.

Das zahlt sich bei einer großen Anzahl an Datensätzen aus und macht sich dann in der Performance bemerkbar, vor allem, wenn wir die Spalte login noch indizieren.

Autor
Kategorien Datenbanken, Coding

PRTG Map