LIKE
am 19.02.2005 15:37:45 von Bart Bailey
Hallo,
ich bin neu bei PHP. Bei einer Datenbank will ich eine Zeile Auswählen,
bei der ein Feld eine Zahl enthält. So ist der Feldinhalt z.B.
"1|4|5|6|9" und ich habe die Zahl "5".
Dies gienge mit:
SELECT * FROM Tabelle WHERE LinkU LIKE '%|$mGabe|%'
wobei mGabe eine Variable mit einer Zahl ist.
Wenn die zahl ber am anfang oder am Ende steht, findet er sie nicht,
weil %|zahl|% nicht zutrifft sondern nur zahl|%.
Wenn ich es aber so formuliere: LIKE '%zahl%' dann trifft es für zahl=2
auch zu, wenn der Inhalt 1|3|22|23 ist.
Das war jetzt etwas kompliziert ausgedrückt, doch was kann ich tun?
Danke!
Re: LIKE
am 19.02.2005 15:57:25 von Hartmut Holzgraefe
Jens Müller wrote:
> Hallo,
>=20
> ich bin neu bei PHP. Bei einer Datenbank will ich eine Zeile Auswähle=
n,=20
> bei der ein Feld eine Zahl enthält. So ist der Feldinhalt z.B.=20
> "1|4|5|6|9" und ich habe die Zahl "5".
Du möchtest die Zahlen in einer zweiten Tabelle halten und mit der
eigentlichen Tabelle über deren Primärschlüssel verknüpfen.
Also etwa so:
CREATE TABLE tabelle (
id INT NOT NULL PRIMARY KEY
/* hier können noch weitere Felder stehen */
);
CREATE TABLE zahlen (
tabelle_id INT NOT NULL,
zahl int,
PRIMARY KEY(zahl, tabelle_id)
);
Deinen Beispieldatensatz von oben kannst du dann mit
INSERT INTO tabelle (id) VALUES (1);
INSERT INTO zahlen (tabelle_id, zahl) VALUES (1,1);
INSERT INTO zahlen (tabelle_id, zahl) VALUES (1,4);
INSERT INTO zahlen (tabelle_id, zahl) VALUES (1,5);
INSERT INTO zahlen (tabelle_id, zahl) VALUES (1,6);
INSERT INTO zahlen (tabelle_id, zahl) VALUES (1,9);
anlegen. Nach allen Einträgen mit einer "5" suchst du dann
mit
SELECT ...
FROM tabelle JOIN zahlen ON tabelle.id =3D zahlen.tabelle_id
AND zahlen.zahl =3D 5
Zugegeben, der Aufwand beim Einfügen der Daten mag etwas
höher erscheinen. Aber dafür kann direkt ohne Tricks auf
die benötigten Daten zugegriffen werden.
Da dabei auch Index-Informationen genutzt werden können
geht das zudem noch wesentlich schneller als dein Ansatz
über LIKE bei dem für jede Abfrage alle Tabellenzeilen
durchsucht werden müssen (full table scan).
--=20
Hartmut Holzgraefe, Senior Support Engineer .
MySQL AB, www.mysql.com
Don't miss the MySQL Users Conference 2005: http://www.mysqluc.com
Re: LIKE
am 19.02.2005 16:34:27 von Magnus Rosenbaum
Hartmut Holzgraefe wrote:
> Jens Müller wrote:
>> ich bin neu bei PHP. Bei einer Datenbank will ich eine Zeile
>> Auswählen, bei der ein Feld eine Zahl enthält. So ist der Feldinhalt
>> z.B. "1|4|5|6|9" und ich habe die Zahl "5".
Hier eine Funktion dafür (allerdings mit Komma statt Pipe):
// WHERE Bedingung für das Vorkommen in einem Feld mit Komma-Array
// (string) $field Datenbankfeldname
// (int) $value Zu findender Wert
function where_in_array($field,$value) {
return " ( ".$field." LIKE '%,".$value.",%' OR ".
$field." LIKE '" .$value.",%' OR ".
$field." LIKE '%,".$value. "' OR ".
$field." LIKE '" .$value. "' ) ";
}
Alternativ geht's auch mit REGEX, aber ob das von der Performance her
besser ist, hat hier auch schon mal jemand in Frage gestellt.
> Du möchtest die Zahlen in einer zweiten Tabelle halten und mit der
> eigentlichen Tabelle über deren Primärschlüssel verknüpfen.
ja, das wäre die akademisch richtige Methode.
> Da dabei auch Index-Informationen genutzt werden können
> geht das zudem noch wesentlich schneller als dein Ansatz
> über LIKE bei dem für jede Abfrage alle Tabellenzeilen
> durchsucht werden müssen (full table scan).
Richtig. Wenn man aber nur selten eine solche Abfrage macht und meistens
nur das Array an sich lesen oder schreiben will, dann ist wahrscheinlich
eher diese "Array als String"-Methode performanter.
Ich hab jedenfalls auch schon öfter gehört, dass Leute mit
Referenztabellen Performanceprobleme bekommen haben. Aber das wird sicher
sowohl von der Art der Abfragen als auch vom verwendeten Datenbanksystem
abhängen.
Außerdem muss man sich bei den Referenztabellen um referenzielle
Integrität kümmern, was ja auch nicht grade trivial ist.
cu, Magnum
--
Carl Magnus Rosenbaum M.A. Tel: 089 - 700 666 26
Administration - Programmierung - Weiterbildung Fax: 089 - 700 666 86
http://cmr.forestfactory.de/ Mobil: 0163 - 700 666 2
Re: LIKE
am 19.02.2005 20:41:32 von Christoph Hermann
Magnus Rosenbaum schrieb:
Moin,
> Außerdem muss man sich bei den Referenztabellen um referenzielle
> Integrität kümmern, was ja auch nicht grade trivial ist.
Dafür gibt es Foreign keys.
Christoph
Re: LIKE
am 19.02.2005 22:11:25 von Niels Braczek
Christoph Hermann schrieb:
> Magnus Rosenbaum schrieb:
>
>>Außerdem muss man sich bei den Referenztabellen um referenzielle
>>Integrität kümmern, was ja auch nicht grade trivial ist.
>
> Dafür gibt es Foreign keys.
Die aber nicht überall unterstützt werden.
MfG
Niels
Re: LIKE
am 20.02.2005 02:36:40 von Dennis Birkholz
Jens Müller schrieb:
> Hallo,
>
> ich bin neu bei PHP. Bei einer Datenbank will ich eine Zeile Auswählen,
> bei der ein Feld eine Zahl enthält. So ist der Feldinhalt z.B.
> "1|4|5|6|9" und ich habe die Zahl "5".
> Dies gienge mit:
> SELECT * FROM Tabelle WHERE LinkU LIKE '%|$mGabe|%'
> wobei mGabe eine Variable mit einer Zahl ist.
> Wenn die zahl ber am anfang oder am Ende steht, findet er sie nicht,
> weil %|zahl|% nicht zutrifft sondern nur zahl|%.
> Wenn ich es aber so formuliere: LIKE '%zahl%' dann trifft es für zahl=2
> auch zu, wenn der Inhalt 1|3|22|23 ist.
> Das war jetzt etwas kompliziert ausgedrückt, doch was kann ich tun?
>
> Danke!
Du musst das mit einer RegEX machen:
SELECT * FROM tabelle WHERE LinkU REGEXP '(^|,)$mGabe(,|$)'
Ich habe jetzt mal die | durch Komma ersetzt, weil | in den RegEX eine
Funktion hat, du kannst die natürlich mit \ Escapen, macht es aber
unübersichtlich.
Viele Grüße,
Dennis
Re: LIKE
am 20.02.2005 18:43:50 von Michael Fesser
.oO(Niels Braczek)
>Christoph Hermann schrieb:
>> Magnus Rosenbaum schrieb:
>>
>>>Außerdem muss man sich bei den Referenztabellen um referenzielle
>>>Integrität kümmern, was ja auch nicht grade trivial ist.
>>
>> Dafür gibt es Foreign keys.
>
>Die aber nicht überall unterstützt werden.
Das ist kein Argument gegen vernünftiges DB-Design. Wenn das DBMS keine
referentielle Integrität unterstützt, dann hat sich halt die Applikation
selbst darum zu kümmern.
Micha
Re: LIKE
am 20.02.2005 19:27:39 von Niels Braczek
Michael Fesser schrieb:
> .oO(Niels Braczek)
>>Christoph Hermann schrieb:
>>>Magnus Rosenbaum schrieb:
>>>
>>>>Außerdem muss man sich bei den Referenztabellen um referenzielle
>>>>Integrität kümmern, was ja auch nicht grade trivial ist.
>>>
>>>Dafür gibt es Foreign keys.
>>
>>Die aber nicht überall unterstützt werden.
>
> Das ist kein Argument gegen vernünftiges DB-Design. Wenn das DBMS keine
> referentielle Integrität unterstützt, dann hat sich halt die Applikation
> selbst darum zu kümmern.
Full ACK. Genau das sagte Magnus ja schon.
MfG
Niels