Da jeder ja seine eigenen Vorstellungen hat was "Ähnlich" bedeutet, wird es der beste Ansatz sein eigene Äquivalenzen zu setzen. Bsp:
C = K #Karl- Carl
pf = f #Sopfie- Sofie
Ohne jetzt auf meinem Vorschlag rumreiten zu wollen: Mit solchen gezielten Äquivalenzen wirst du immer irgendwas übersehen, sie sind zu speziell. Oder du "äquivalenzifizierst" so dermaßen, dass kaum noch Unterschiede zu erkennen sind. Im Grunde baust du damit den gleichen Kram, der bereits als soundex() etc. existiert.
Mit n-Grammen hingegen würden deine beiden Beispiele schon von Haus aus als nahezu identisch ausgegeben, ohne, dass du dir Gedanken darüber machen musst, welche Buchstabenkombinationen du als gleichwertig betrachten möchtest. Wie ich bereits schrieb: So simpel das Prinzip auch sein mag, die Leistung ist enorm.
In meinen Fall mit den Vornamen wird es Sinn machen einen Vornamen als Gruppe in eine weitere Datenbank zu schreiben und diese gesamte Gruppe dann als Suchwörter für die erste DB verwenden.
Das kommt mir nun wirklich äußerst aufwändig und fehlerträchtig vor. Weisst du, wie viele Vornamen es gibt, die gewollt beknackten ("Lennoks Mädden") noch nicht einmal mitgezählt?
Und wenn du schon selbst eine weitere Tabelle vorsiehst … für die Suche nach Vorschlägen reicht ein einzelner SQL-Befehl:
> select count(*) as wert,person.name from person join ngramm on person.id = ngramm.person where gramm in ("so", "sof", "of") group by person.id order by wert desc;
+------+--------+
| wert | name |
+------+--------+
| 2 | Sofia |
| 2 | Sofie |
| 1 | Sophia |
+------+--------+
> show columns from person;
+-------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(100) | NO | | NULL | |
+-------+--------------+------+-----+---------+----------------+
> show columns from ngramm;
+--------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+---------+------+-----+---------+-------+
| gramm | char(3) | NO | MUL | NULL | |
| person | int(11) | NO | | NULL | |
+--------+---------+------+-----+---------+-------+