Schnelle Anonymisierung in DB-Tabellen
Aufgabenstellung ist es, mölichst schnell und unkompliziert eine Tabelle mit typischen Benutzerdaten (z.B. Vor- und Nachname, Geburtsdatum) zu anonymisieren. Aufgrund der Größe der Tabelle mit ca. 35.000 Einträgen erachten wir es als ausreichend, die jeweiligen Spalten „durcheinanderzuwürfeln“, so dass andere Kombinationen aus Vor- und Nachnamen entstehen als in der Ausgangstabelle. Und am besten sollten keine externen Tools verwendet werden, also kein Perl, Java etc.
Ausgangstabelle:
1 | Firstname1 | Lastname1 |
2 | Firstname2 | Lastname2 |
3 | Firstname3 | Lastname3 |
Wir generieren zunächst 3 temporäre Tabellen, in die jeweils ein Attribut gespeichert wird:
CREATE TABLE id_temp
(
id serial NOT NULL,
source_id integer
);
CREATE TABLE firstname_temp
(
id serial NOT NULL,
firstname character varying(70)
);
CREATE TABLE lastname_temp
(
id serial NOT NULL,
lastname character varying(70)
);
und eine Zieltabelle mit derselben Strunktur wie die Ausgangstabelle:
CREATE TABLE shuffeled
(
id integer NOT NULL,
firstname character varying(70),
lastname character varying(70)
);
Dann speichern wir in die temporären Tabellen Werte aus der Ausgangstabelle und nutzen dabei die SQL-Random()-Funktion. Wichtig ist auch das Serial-Feld in den temporären Tabellen, das eine Nummerierung der Zeilen sicherstellt.
INSERT INTO id_temp(source_id) SELECT id from original ORDER BY RANDOM();
INSERT INTO firstname_temp(firstname) SELECT firstname from original ORDER BY RANDOM();
INSERT INTO lastname_temp(lastname) SELECT lastname from original ORDER BY RANDOM();
Das Resultat sind drei Tabellen, die zufällig angeordnete Abfolgen der Spalteninhalte der Ausgangstabelle beinhalten.
id_temp:
id | source_id |
1 | 2 |
2 | 1 |
3 | 3 |
firstname_temp:
id | firstname |
1 | firstname3 |
2 | firstname2 |
3 | firstname1 |
lastname_temp:
id | lastname |
1 | firstname2 |
2 | lastname1 |
3 | lastname3 |
Und als letzer Schritt werden diese zusammengeführt in die Zieltabelle:
INSERT INTO shuffeled (id, firstname, lastname)
SELECT id_temp.source_id AS id,
firstname_temp.firstname AS firstname,
lastname_temp.lastname AS lastname
FROM id_temp, firstname_temp, lastname_temp
WHERE id_temp.id=firstname_temp.id
AND id_temp.id=lastname_temp.id;
Et voila, wir erhalten eine Tabelle mit zufällig angeordneten Kombinationen:
1 | Firstname2 | Lastname3 |
2 | Firstname3 | Lastname1 |
3 | Firstname1 | Lastname2 |
Danach müssen nur noch die temporären Tabellen wieder entfernt werden. Statt in eine Zieltabelle sch schreiben, kann natürlich auch die Ausgangstabelle beschrieben werden.
In der tatsächlichen Anwendung – die noch einiges komplexer ist und ca. 36.000 Einträge hat – dauert das ganze auf einem Standard-PC ca. 6 Sekunden!