Entwickler-Ecke

Datenbanken - Table ohne Doubletten?


noreux - Mi 24.10.07 12:29
Titel: Table ohne Doubletten?
Hallo!

Ich habe eine ganz normale Datenbank, die ich mit Table und Datasource auch gut ansprechen kann. In meiner Datenbank gibt es nur ein Feld in welches mehrere tausend Datensätze reinmüssen. Es ist im Prinzip also nur eine Liste, den werten ist nichts zugewiesen. Kann ich beim hinzufügen eines einzelnen Wertes irgendwie auf Doubletten prüfen, sodass keine doppelten hinzugefügt werden? Sollte aber relativ performant laufen, da später weitere datenbanken dazukommen mit mehreren millionen werten. Gibts da ne gute Möglichkeit?
mfg
NoR


noidic - Mi 24.10.07 12:43

leg auf das Feld nen Primärschlüssel oder nen unique constraint, dann kriegst du von der Datenbank ne Exception wenn ein Datensatz doppelt eingefügt werden soll.


noreux - Mi 24.10.07 12:54

danke für die schnelle antwort!
Kannst du mir auch noch sagen wie ich den primärschlüssel setzen kann?
gruß
NoR


mkinzler - Mi 24.10.07 13:15

Wenn du unter einer "normalen Datenbank" eine dBase- oder Paradox-Tabelle verstehst, dann bei der Anlage in der Datenbankoberfläche.


noidic - Mi 24.10.07 13:26

Was für ein Datenbanksystem ist es denn?


noreux - Mi 24.10.07 13:30

Hi!
Ja es ist eine Paradox Tabelle. Sie wird bei mir aber während der Laufzeit erstellt mit:

table1.active:=false;
table1.tablename:=datenbank;
table1.fielddefs.add('Neu', ftString, 50, false);
Table1.CreateTable;


Danach füge ich die Datensätze hinzu, also das Feld "Neu" soll dann der Primärschlüssel sein, die datenbankoberfläche steht mir also nicht zur verfügung, weil die datenbanken variabel erstellt werden.

mfg
NoR


noreux - Mi 24.10.07 15:06

und noch ne kleine Frage: Nachdem ich ne Stringlist in die Datenbank laden wollte, bricht er mir nach 2,5 mio. datensätzen ab und sagt dass der datenbank keine einträge mehr hinzugefügt werden kann. Die DB-File ist genau 128 MB groß, also vermute ich mal dass das die magische grenze bei paradox-tabellen ist. Jetzt meine Frage, kann ich das Limit irgendwie raufsetzen, oder gibt es ein ähnliches datenbankmodel mit mehr Kapazitäten (und mehr Performance wäre auch nicht verkehrt) auf welches ich recht einfach umsteigen könnte?
gruß
Nor


mkinzler - Mi 24.10.07 15:50

Interbase/FireBird, MSSQL, Oracle express, DB2 express, ...
cross posting: http://www.delphipraxis.net/topic121443_welches+datenbankmodell+am+performantesten.html


noreux - Mi 24.10.07 20:58

danke für die infos, werde es mal mit der firebird lösung probieren. Wäre aber trotzdem noch cool wenn mir jemand sagen könnte wie ich bei ner normalen db diesen primärschlüssel setzt ohne der Oberfläche?


mkinzler - Mi 24.10.07 21:04

In dem du einen Index anlegst:

Delphi-Quelltext
1:
table1.IndexDefs.Add('iNeu', 'Neu', [ixPrimary,ixUnique]);                    


mkinzler - Mi 24.10.07 21:05

user profile iconmkinzler hat folgendes geschrieben:
In dem du einen Index anlegst:

Delphi-Quelltext
1:
table1.IndexDefs.Add('iNeu', 'Neu', [ixPrimary,ixUnique]);                    

oder die Tabelle per SQL anlegst.


noreux - Mi 24.10.07 21:27

danke funktioniert!


noreux - Fr 26.10.07 11:43

Moin, hab noch n kleines problem, der DB hab ich jetzt den Index mitgegeben so wie du es gepostet hast, funktioniert auch in sofern dass er keine Duplikate mehr zulässt. Wenn ich jetzt aber per Schleife Datensätze speichern will, bricht er mir bei einer Duplette mit Message "Indexfehler" die ganze Schleife ab. Wie kann ich es machen, dass er den Fehler ignoriert, die Duplette dann eben nicht speichert und zum nächsten weiter geht? Mein Code sieht an der Stelle so aus:


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
liste: TStringlist.Create;
liste.LoadFromFile('neuelistedieindiedbsoll.txt')

for i:=0  to liste.count-1 do
  begin
     table1.edit;
     try
       begin
         Table1.insert;
         Table1.FieldByName('Neu').AsString:=liste.Strings[i];
       end
        except ShowMessage('Konnte den Eintrag nicht machen');
     end;
     table1.post;
 end;

liste.Destroy;


Eigentlich sollte er ja im Fehlerfall die Message auswerfen, er bringt aber eben nur "Indexfehler" und bricht die Schleife ab. Irgendwelche Tipps?
gruß
noreux


noidic - Fr 26.10.07 12:38

Bin mir jetzt nnicht ganz sicher, aber kann es sein, dass der Fehler erst beim post auftritt?


Alpha_Wolf - Fr 26.10.07 12:54

Ich würde dir auch dringend raten mit Transaktionen zu arbeiten.. Somit kannst du sicher sein das auch die komplette Aktion durchgeführt wird und nicht etwa nur die Hälfte der Daten in die DB geschrieben wird, weil ein Fehler aufgetreten ist.

Besonders schont es auch die DB Verbindung da es nur einmal auf die DB zugreift. Nämlich ganz am Schluss beim Commit.

Was es mit Transaktionen auf sich hat findest du in der Forumssuche...