Wenn ich mich richtig erinnere, ist md5() doch dafür gemacht, schnell eine Prüfsumme eines großen Strings zu rechnen?
Ich will einfach nur schauen ob ein Text schon mal in der Datenbank ist, und dachte das wäre ja geeignet
Wenn ich mich richtig erinnere, ist md5() doch dafür gemacht, schnell eine Prüfsumme eines großen Strings zu rechnen?
Ich will einfach nur schauen ob ein Text schon mal in der Datenbank ist, und dachte das wäre ja geeignet
ungetestet und nie versucht, aber:
Kommt drauf an wie groß/lang der Text ist.
Wenn Dein Text mehrere hundert Zeichen lang sein kann und Du nach dem gesamten Text suchen musst, dann wäre es eine komische query an den Sql-Server
Dann würde es wohl wirklich Sinn machen ne Prüfsumme von dem zu speichernden Text gleich mit zu speichern.
In etwa:
tbl_texte:
`id`-- primary key
`text`
`md5` -- unique index
md5 also index, damit Du nicht die ewig langen Texte indexieren musst (was bissl blöd wäre =)
unique index, damit Du keine doppelten Texte speichern kannst.
Den md5 kannst Du auch gleich dem Sql-Server überlassen:
Dann bekommst Du ein Feedback, ob der gleiche Text schon vorhanden war.
Spart eine vorangehende Such-Query.
Und was bekomme ich zurück, weil wenn der text schon da ist, will ich seine ID haben.. spalte ist `id`
naja, dann wäre der riesen Text wieder an den Sql-Server geschickt.
Dann evtl doch den md5 via PHP berechnen.
INSERT INTO `tbl_texte`
(`text`,`md5`)
VALUES (:text,:md5)
SELECT `id` FROM `tbl_texte`
WHERE `md5` = :md5;
UPDATE `tbl_texte` SET `text` = :text, `md5` = :md5
WHERE `id` = :id
Alles anzeigen
Die md5 dann immer per PHP erstellen.
BTW: eigtl brauchst Du gar keine id, da der md5 ja unique sein sollte/muss - md5 könnte also auch primary key sein.
ABER es soll wohl sinnvoller sein den fortlaufende numerische ids zu verwenden anstatt lange Strings. Kommt aber auch wieder auf die Masse an Daten an.
Die Masse der Daten können halt schon mal 6000 Datensätze werden evtl
@Phib S, ich weis wie ich ne Spalte auslesen kann
Joa, danke
Dann wäre es evtl sinnvoll 2 tbl abzulegen.
tbl_texte:
`id`-- primary key
`text`
tbl_md5:
`id_texte` -- fremdschlüssel (foreign key) von tbl_texte
`md5` -- unique index
Durch den Fremdschlüssel stehen die beiden Tabellen in Beziehung und es kann nur eine in tbl_texte existierende `id` in tbl_md5 eingefügt werden.
Wenn Du also nur prüfen willst, ob ein Text schon existiert, dann suchst Du in der "schnellen" Tabelle `tbl_md5` nach dem md5 Hash.
Natürlich holst Du Dir dabei auch gleich die `id`, um bei Bedarf den Text aus `tbl_texte` via `id` zu lesen.
Musste Du aber abwiegen. Denn ein Insert wird dann über 2 Tabellen laufen (Stichworte "BEGIN TRANSACTION", "COMMIT", "ROLLBACK").
Wäre halt mMn für sehr viele Datensätze angebracht.
btw: gerade drüber gestolpert: http://stackoverflow.com/quest…t-field-in-select-results
(als vorschau ect evtl)
EDIT:
ach da fällt mir gleich wieder so viel ein ..
Du kannst für INSERTs auch einen Trigger erstellen:
CREATE TRIGGER 'triggername'
AFTER INSERT ON `tbl_texte`
FOR EACH ROW
INSERT INTO `tbl_md5`
SET `id` = NEW.`id`, `md5` = md5(NEW.`text`);
Also wird bei jedem INSERT INTO `tbl_texte` der md5 und die id in `tbl_md5` geschickt =)
(wenn man trigger mag)
Ich bin überhaupt net SQL fit
Verstehe so an die 70% deines Textes, davon ist bestimmt 50% logisch erschlossen
Ne Anleitung wär ganz cool
dankö
@Basiii
okiedokie
hab versucht alles so einfach wie möglich in den comments zu erklären:
-- erstelle datenbank:
CREATE SCHEMA `db_name`
DEFAULT CHARACTER SET 'utf8'
COLLATE 'utf8_general_ci' ;
-- erstelle tabelle `texte`:
CREATE TABLE `db_name`.`texte` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT, -- UNSIGNED heißt: keine negativen werte (also kein -1 ...)
`text` LONGTEXT NOT NULL,
PRIMARY KEY (`id`)
);
-- erstelle tabelle `md5`:
CREATE TABLE `db_name`.`md5` (
`id_texte` INT UNSIGNED NOT NULL,
`md5` VARCHAR(32) NOT NULL,
PRIMARY KEY (`id_texte`),
UNIQUE INDEX `md5_UNIQUE` (`md5` ASC) -- column `md5` kann nur einmal in der tabelle vorkommen (einzigartig)
);
-- beziehung zwischen den tabellen herstellen:
ALTER TABLE `db_name`.`md5` -- ändere tabelle `md5`
ADD CONSTRAINT `id_tbl_texte` -- füge hinzu: constraint (zwang) vom namen `id_tbl_texte`
FOREIGN KEY (`id_texte`) -- setze fremdschlüssel column `id_texte` der tabelle `md5`
REFERENCES `db_name`.`texte` (`id`) -- reference column `id` der tabelle `texte`
ON DELETE CASCADE -- beim löschen der `id` in der tabelle `texte` den zugehörigen eintrag in tabelle `md5` auch löschen
ON UPDATE CASCADE; -- beim updaten der `id` in der tabelle `texte` den zugehörigen eintrag in tabelle `md5` auch updaten
-- trigger (auslöser) erstellen:
-- (wir wollen nicht in beide tabellen speichern. inserts in die tabelle `md5` soll der trigger für uns übernehmen)
CREATE TRIGGER `insert_in_tbl_md5`
AFTER INSERT ON `db_name`.`texte`
FOR EACH ROW
INSERT INTO `db_name`.`md5`
SET `id_texte` = NEW.`id`, `md5` = md5(NEW.`text`);
-- und das gleiche für updates:
CREATE TRIGGER `update_in_tbl_md5`
AFTER UPDATE ON `db_name`.`texte`
FOR EACH ROW
UPDATE `db_name`.`md5`
SET `md5` = md5(NEW.`text`)
WHERE `id_texte` = NEW.`id`;
Alles anzeigen
Durch die Beziehung (FOREIGN KEY) ist es jetzt nicht möglich zB eine `id_texte` mit dem Wert 2 in die Tabelle `md5` einzufügen, wenn in der Tabelle `texte` nicht auch eine `id` mit dem Wert 2 existiert.
Kurz und einfach:
Inhalt Tabelle `texte`
Inhalt Tabelle `md5`
id_texte | md5
-----------------------
1 | xxxxxxmd5hash...
2 | xxxxxxmd5hash...
3 | xxxxxxmd5hash... -- FEHLER: id '3' existiert nicht in tabelle `texte` (ERROR 1452: 1452: Cannot add or update a child row: a foreign key constraint fails)
// aber wir ändern sowieso nix aktiv an der tabelle `md5`
// das überlassen wir dem sql server via trigger und foreign key
Alles anzeigen
INSERT:
INSERT INTO
`db_name`.`texte`
(`text`)
VALUES ('this is a looooooooooong text ....');
-- beim INSERT löst der TRIGGER ein INSERT in die tabelle `md5` aus.
-- der md5 hash wird also durch den sql server erstellt und geschrieben
-- die `id` ist fortlaufend, wird also vom sql server übernommen
Alles anzeigen
UPDATE:
UPDATE
`db_name`.`texte`
SET
`text`='this is another looooooooooong text ....'
WHERE
`id`='1';
-- beim UPDATE löst der TRIGGER ein UPDATE in die tabelle `md5` aus.
-- der md5 hash wird also durch den sql server ge-updated
-- die `id` in tabelle `md5` bleibt gleich - logisch =)
Alles anzeigen
DELETE:
DELETE FROM
`db_name`.`texte`
WHERE
`id`='1';
-- durch die beziehung zwischen den tabellen (foreign key) wurde festgelegt, dass
-- ON DELETE CASCADE - also beim löschen ~übernehmen
-- dadurch wird der zugehörige eintrag in tabelle `md5` auch gelöscht
Alles anzeigen
SELECT:
-- prüfen, ob text schon vorhanden:
SELECT
`id_texte`
FROM
`db_name`.`md5`
WHERE
`md5` = :md5;
-- :md5 ist platzhalter für den via PHP erstellten md5 hash des gesuchten textes
-- -- --
-- wir kennen jetzt die id, also laden wir den text:
SELECT
`id`,
`text`
FROM
`db_name`.`texte`
WHERE
`id` = :id;
-- :id ist platzhalter für die id, die wir zuvor aus der suche bekommen haben
-- -- --
-- alternativ/sinnvoller :: suche und laden in einem:
SELECT
`A`.`id`,
`A`.`text`
FROM
`db_name`.`texte` AS `A`
JOIN `db_name`.`md5` AS `B` -- ~"nutze tabelle `md5` als kürzel `B`"
ON (`A`.`id` = `B`.`id_texte`) -- aber nur wo die `id`(tabelle `texte`) gleich `id_texte`(tabelle `md5`) ist
WHERE
`md5` = :md5;
Alles anzeigen
Da geht bestimmt noch was, aber das Modell an sich sollte funktionieren.
Viiiiieleeeeen dank
Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!
HTML-Seminar.de - mit Videos zum schnellen Lernen, wie man eine Website selbst erstellt.