Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Basic-Frage (https://www.delphipraxis.net/173230-basic-frage.html)

erich.wanker 13. Feb 2013 13:25

Datenbank: firebird • Version: 2.1 • Zugriff über: ZEOS 6.6.6

Basic-Frage
 
Hallo Leute...
eine sehr einfache Frage:

Ich möchte einen Datensatz kategorisieren ( über 40 dynamische AND/OR Kategorie-Möglichkeiten stehen zur Verfügung)

Bis dato (oh Gott, ich trau es mir gar nicht zu sagen..)schreib ich in ein "1000 char" Feld
einen String wie diesen: a1c5d2a2d4

Code:
a1 = "Deutschland"
c5 = "Privatperson"
d2 = "BMW"
ect
Nun suche ich alle Privatpersonen aus Deutschland die einen BMW fahren

select X from Y where ..
and feld containing "a1"
and feld containing "c5"
and feld containing "d2"

...


ist natürlich a Wahnsinns Performancebremse ..

Wie macht man das OPTIMAL?

Vielen Dank

DeddyH 13. Feb 2013 13:30

AW: Basic-Frage
 
Normalisierung

Morphie 13. Feb 2013 13:33

AW: Basic-Frage
 
Bei deinem Beispiel würde ich der Tabelle für jedes Attribut ein Feld spendieren:
LAND - VARCHAR(50)
PRIVAT - SMALLINT (0 / 1 = Ja / Nein)
KFZMARKE = VARCHAR(50)

Dann kannst du einfach abfragen:
Code:
SELECT X FROM Y
WHERE LAND = 'Deutschland'
AND PRIVAT = 1
AND KFZMARKE = 'BMW'
Die vorhandenen Daten musst du dann natürlich irgendwie konvertieren...

DeddyH 13. Feb 2013 13:35

AW: Basic-Frage
 
Ich würde eher für Länder, Automarken etc. jeweils eine eigene Tabelle anlegen und die Fremdschlüssel darauf dann in jeweils einem Feld speichern. Deshalb ja mein Link.

erich.wanker 13. Feb 2013 13:37

AW: Basic-Frage
 
Danke für die Hinweise ...

Zusatzfrage: .. gibts irgendwie eine Art "binäre Lösung" ?

Code:
Feld1  = Vorname
Feld2  = Nachname
Feld3  = Strasse
..
Feld20 = 00000000000000100000000001000000011110000000001

und dafür eine schnelle SQL Abfrage?

Vielen Dank

rapante 13. Feb 2013 13:40

AW: Basic-Frage
 
Hy,
das Zauberwort heisst hier wohl Normalisierung:
Code:
tbl_person
 id
 name
 etc.

tbl_merkmal
 id
 name

tbl_person2merkmal
 id
 id_person
 idmerkmal
SQL:
Code:
SELECT * FROM tbl_person
INNER JOIN tbl_person2merkmal ON tblperson.id = tbl_person2merkmal.id_person
INNER JOIN tbl_merkmal ON tbl_person2merkmal.id_merkmal = tbl_merkmal.id
WHERE tbl_merkmal.name = 'BMW'
...so viele rote Kästen...

DeddyH 13. Feb 2013 13:42

AW: Basic-Frage
 
As I said before :zwinker:

@erich.wanker: Was genau meinst Du mit "binärer Lösung"? Was soll im Feld stehen und wie soll das ausgewertet werden?

erich.wanker 13. Feb 2013 13:58

AW: Basic-Frage
 
Kleines Beispiel:

Code:
SELECT FIRST 300 SKIP 0 * 
FROM DETAIL_DB INNER JOIN KEY_DB ON KEY_DB.INR_OWN = DETAIL_DB.INR

AND KEY_DB.INR_PARENT = 92321 
AND KEY_DB.INR_MENU = 3 AND DETAIL_DB.ERLEDIGT = 0 
AND DETAIL_DB.PERMISSION_FOR_VIEW CONTAINING'a'

AND DETAIL_DB.STATUS_INFORMATION NOT CONTAINING'd1'
AND DETAIL_DB.STATUS_INFORMATION NOT CONTAINING 'z9'
AND DETAIL_DB.STATUS_INFORMATION NOT CONTAINING 'x1'
AND DETAIL_DB.STATUS_INFORMATION CONTAINING 'a1'
AND DETAIL_DB.STATUS_INFORMATION CONTAINING 'b1'

ORDER BY DETAIL_DB.DATE2 ASCENDING, DETAIL_DB.OBJECT_NAME

Das Feld DETAIL_DB.STATUS_INFORMATION ist das besagte "Stringkategorisierungsding"


Cool wäre es wenn ich auf INNER JOIN verzichten könnte, weil ich im Vorfeld schon einige brauche.

Meine binäre Vorstellung wäre:

Code:
Ein Feld hat Wert: 0000000000000000000000000100000100010000011111
und eine Abfrage wäre lt. meiner Phantasie:

Code:
Select X from Y where Feld = "xxxxxxxxxxxx0xxxxx1xxxxx0xxxxxxxxxxxxx11"
and Feld NOT "xxxxxxxxxxxxxxxxxxxxxxxx1xxxxxxxxxxxxxxxxx"
x = egal was auf dieser Position steht

ich hoffe, ich hab mich halbwegs verständlich ausgedrückt

Danke

DeddyH 13. Feb 2013 14:07

AW: Basic-Frage
 
Sollen das jetzt Zahlen sein oder Strings? Das Hauptproblem bleibt doch: Deine Daten sind nicht atomar, da stehen mehrere Werte in einem einzigen Feld. IMO bringt es wenig bis nichts, einen Designfehler durch "krumme Tricks" wie Binärvergleiche ausbügeln zu wollen. Und ob Du nun einen INNER JOIN hast oder 20, welche Rolle spielt das? Sollte Dir das zu unübersichtlich werden, erstelle Dir doch eine Sicht.

jobo 13. Feb 2013 14:33

AW: Basic-Frage
 
Die schnellste und variabelste Lösung wäre m.E. die von Rapante:
http://www.delphipraxis.net/1203324-post6.html

Eine Binär Lösung würde m.E. an der Einschränkung der Zahlentypen leiden, ok schnell, aber untypisch für SQL und in vielen SQL Dialekten wg der notewendigen Binär Operatoren auch nicht ohne weiteres umsetzbar.
(Vermutung: Die Darstellung hier ist zwar textuell, soll aber binär umgesetzt werden)

erich.wanker 13. Feb 2013 14:46

AW: Basic-Frage
 
@DeddyH .. danke für deine Tipps. Bis dato konnte ich mit meiner "schrägen" Lösung so halbwegs gut leben .. Durch die größeren Datenbank-excludes am Anfang des SQL Statements ( where feld = X) und die Range-Begrenzung (meist 300) machten die "containing" Abfragen keinen großen Performanceverluste .. aber es ist nix gscheites ... Ich hab mich immer von mehreren "Inner Join" gedrückt: erstens wegen der komplexität, die bei bestimmten Abfragen entsteht - andererseits wegen Performancebedenken: Wie würdest du die Performancegeschichte beurteilen, wenn ich das oben gepostete SQL Beispiel mit InnerJoin´s lösen würde (jede Tabelle hat ca. 20.000 Datensätze) ?

Danke

Erich

DeddyH 13. Feb 2013 14:49

AW: Basic-Frage
 
Bei entsprechend gesetzten Indizes sollte die Abfrage in Null Komma Nix Ergebnisse liefern. Ob die Indizes richtig gesetzt sind, kannst Du im Execution Plan ermitteln. Dafür gibt es aber hier richtige Experten, ich tue mich in dem Bereich immer etwas schwer mit Erklärungen.

erich.wanker 13. Feb 2013 14:54

AW: Basic-Frage
 
all right :-) - ab jetzt wird die "Normalisierung" gefahren ...

Danke an alle

LiGrü aus dem Gasteinertal

Erich


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:10 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz