Erstell eine dritte Spalte: Hash1_Hash2
und da packst du dann "Hash1 SEPARATOR Hash2" rein. Ist zwar denomalisiert (ich steh drauf
), aber dann hast du sie zusammengefasst und trotzdem noch die Einzelwerte in den anderen Spalten verfügbar.
Und SEPARATOR sollte natürlich nicht Teil des Zeichensatzes von Hash1 und/oder Hash2 sein. Versteht sich ja von selbst.
EDIT: I see, ich habe das Problem falsch interpretiert.
Du brauchst also für die dritte Spalte eine Funktion, die aus "Hash1 verknüpft mit Hash2" ein eindeutiges Ergebnis liefert, das dasselbe Ergebnis ist wie "Hash2 verknüpft mit Hash1". Höhere Mathematik...
Spontane Idee #1:
4 Spalten: Hash1, Hash2, Hash1_2 und Hash2_2 und jeweils UNIQUE (Hash1, Hash2) und UNIQUE (Hash2_1, Hash2_2) und die Werte entsprechend vertauscht speichern.
Spontane Idee #2.1:
Lös es in deiner Programmlogik:
Code:
SELECT count(*) FROM Table WHERE Hash1 = x AND Hash2 = y OR Hash1 = y AND Hash2 = x
if(result == 0) {
INSERT ...
}
Spontane Idee #2.2:
Das geht natürlich auch in einem einzelnen Query:
Code:
INSERT INTO Table (Hash1, Hash2, Similarity)
SELECT 1, 2, 42.00 FROM DUAL
WHERE NOT EXISTS (SELECT * FROM Table WHERE Hash1 = 1 AND Hash2 = 2 OR Hash1 = 2 AND Hash2 = 1)
(keine Ahnung ob SQLite das beherrscht. DUAL ist ein Virtueller Table, den man benutzen kann, wenn eigentlich auf keinen Table zugegriffen wird, aber man wegen der Syntax einen angeben muss)
Spontane Idee #3:
Als Funktion, um die beiden Hashes in beliebiger Reihenfolge eindeutig zu verknüpfen und in einer dritten Spalte zu speichern könntest du einfach Folgendes tun:
Code:
SEPARATOR = "-";
hash1 = 3;
hash2 = 4;
if(hash1 < hash2) {
combinedHash = hash1+SEPARATOR+hash2; // also in dem Fall: "3-4"
} else {
combinedHash = hash2+SEPARATOR+hash1; // -> "4-3"
}
INSERT INTO Table (Hash1, Hash2, CombinedHash, Similarity) VALUES (hash1, hash2, combinedHash, 42.00)
Dann steht immer der kleinere Wert vorne. Und somit ist die Spalte eindeutig definiert. Der SEPARATOR "-" ist nicht im Alphabet von hash1 und hash2 enthalten (sind ja einfach nur Zahlen mit Alphabet 0123456789). Dasselbe geht natürlich auch für Strings, wobei man wieder ein Zeichen braucht, das in keinem String vorhanden ist. Hier könnte man die beiden Hashes vorher durch einen Base64 Encoder jagen, dann hat man noch einige unbenutzte Zeichen zur Verfügung, die man als SEPARATOR missbrauchen kann.
Es reicht nicht die zwei Zahlen einfach (ohne SEPARATOR) zu konkatenieren: 1 + 222 wäre sonst dasselbe wie 12 + 22.