Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   UniDac Select & Edit (Anfängerfrage) (https://www.delphipraxis.net/177887-unidac-select-edit-anfaengerfrage.html)

sundance 4. Dez 2013 09:03

Datenbank: MySQL • Version: 5 • Zugriff über: UniDAC

UniDac Select & Edit (Anfängerfrage)
 
Hallo zusammen,

ich teste gerade die UniDAC-Komponenten (wir möchten unsere firmeninterne Applikation (Kommandozeilenprogramm) als Stand-alone exe ohne zusätzliche DLL ausliefern).

Der erste Test besteht darin, einen Datensatz einzulesen, ein paar Felder abzuändern und wieder zurückzuschreiben.
Ich habe das so gemacht (die try/except-Blöcke habe ich hier weggelassen):
Delphi-Quellcode:
uniConn := TUniConnection.Create(nil);
uniQuery := TUniQuery.Create(nil);

try
  // Datenbankverbindung
  uniConn.Server      := dbHost;
  uniConn.Port        := 3306;
  uniConn.Username    := dbUser;
  uniConn.Password    := dbPassword;
  uniConn.Database    := dbName;
  uniConn.ProviderName := TMySQLUniProvider.GetProviderName;
  uniConn.Open;

  // Abfrage
  uniQuery.Connection := uniConn;
  uniQuery.SQL.Text   := Format('SELECT * FROM %s WHERE hostname=''%s''',[dbTable, ComputerName]);                                
  uniQuery.Open;       // Datenbankabfrage durchführen
  uniQuery.First;      // und auf erstem Datensatz positionieren
  if not uniQuery.Eof then begin
    stUser := uniQuery.FieldByName('username').AsString;
    expDate := uniQuery.FieldByName('reset_date').AsDateTime;

    // Felder aktualisieren
    uniQuery.Edit;
    uniQuery.FieldByName('last_update').AsDateTime := Now;
    uniQuery.Post;
  end;
  uniQuery.Close;

finally
  uniConn.Free;
  uniQuery.Free;
end;
Beim "uniQuery.Post" gibt's dann eine Exception (Fehler in SQL-Statement near "index=3234").
"index" ist ein AutoIncrement-Feld in der Tabelle und kann natürlich nicht geschrieben werden.

Fragen:
- Stimmt meine Vorgehensweise prinzipiell mit Edit/Post?
- Wie kann man das zum Server geschickte SQL-Statement überprüfen?
- Was ist zu tun bzgl. des Fehlers mit "index"? Kann das Feld vor dem Post entfernt werden?

Ich weiß, dass es auch bei UniDAC ein Forum gibt - aber die Experten sind nun mal hier...

.sundance.

sx2008 4. Dez 2013 10:29

AW: UniDac Select & Edit (Anfängerfrage)
 
An deinem Code ist soweit alles richtig.
4 Kleinigkeiten:
Delphi-Quellcode:
// QuotedString statt ''
uniQuery.SQL.Text := Format('SELECT * FROM %s WHERE hostname=%s',[dbTable, QuotedString(ComputerName)]);
Delphi-Quellcode:
uniQuery.Open; // Datenbankabfrage durchführen
// nach einem Open steht die Datenmenge immer auf dem 1. Datensatz (aber nur wenn die Menge zuvor geschlossen war)
// uniQuery.First; // und auf erstem Datensatz positionieren - braucht man nicht
Eof nimmt man wenn man durch das Dataset iterieren möchte
Um zu prüfen ob überhaupt Datensätze vorhanden sind verwendet man IsEmpty
Delphi-Quellcode:
// if not uniQuery.Eof then begin
if not uniQuery.IsEmpty then begin
Beim beschreiben der Felder kann man die kürzere Schreibweise verwenden.
Beim Lesen sollte man es aber die AsXXXXX-Methoden verwenden um eine Ungültige Variantumwandlung Exception zu vermeiden
Delphi-Quellcode:
// Felder aktualisieren
uniQuery.Edit;
uniQuery['last_update'] := Now; // kürzer und "schöner" (ist aber auch Geschmacksache)
uniQuery.FieldByName('last_update').AsDateTime := Now;
uniQuery.Post;
Jetzt nur zu deinem Problem mit dem Autoincrementfeld "index".
Die VCL muss wissen dass das Autoincfeld nicht upgedatet werden darf.
Prüfe mal welchen Inhalt
Delphi-Quellcode:
uniQuery.FieldByName('index').ProviderFlags
hat.
Notfalls muss man von Hand eingreifen und die Flags ändern.
Eigentlich müsste das UniDAC schon richtig machen (alte Version?)

sundance 4. Dez 2013 11:45

AW: UniDac Select & Edit (Anfängerfrage)
 
Hallo sx2008,

vielen Dank für deine Tipps (ist echt deutlich schlanker... Schade, dass die Doku da ein wenig mager ist).
Vor dem Aufruf von "Post" haben die ProviderFlag folgenden Inhalt: [pfInUpdate..pfInWhere]
(hab's mal auf [pfHidden] gesetzt -> keine Veränderung)

Alte Version ist nicht der Fall (ist vom September 2013)

.sundance.

nahpets 4. Dez 2013 14:04

AW: UniDac Select & Edit (Anfängerfrage)
 
Hallo,

warum nicht in etwa so:
Delphi-Quellcode:
uniQuery.SQL.Text := Format('update %s set last_update = %f WHERE hostname = %s',[dbTable,now,QuotedString(ComputerName)]);
uniQuery.ExecSql;
Damit kommt "niemand" auf die Idee, index zu aktualisieren.
Mein Erfahrung aus den letzten "Jahrzehnten" ist, dass das Update einer Tabelle via Query, Edit und Post nicht bei allen Datenbanken immer reibungslos funktioniert.

In Deinem Fall versucht die Query (vermutlich) alle mit "Select * from" geholten Spalten per Post in die Datenbank zu schreiben. Sie "weiß" nicht, das index nicht geschrieben werden darf, dies "weiß" nur die Datenbank. Daraus dürfte der auftretende Fehler resultieren.

Das direkte Update dürfte auch schneller sein, als erst die Daten zu holen, dann im Programm zu ändern und dann zu schreiben. Mit dem Update ist exakt ein Datenbankzugriff erforderlich.

sundance 4. Dez 2013 14:40

AW: UniDac Select & Edit (Anfängerfrage)
 
Hallo Stephan,

der Gedanke mit
Delphi-Quellcode:
ExecSQL
ist mir auch schon durch den Kopf gegangen, und wäre auch bestimmt nicht komplizierter als Edit/Post. Aber im Beispiel ist es nur ein Feld, welches aktualisiert werden muss - in der "echten" Anwendung sind es aber deutlich mehr (5-10) und da wird der "Zusammenbau" des SQL-Statements doch etwas unübersichtlicher.

Ich habe mittlerweile auch von Devart eine Lösung für das index-Problem erhalten:
Zitat:

The point is that the INDEX is a MySQL reserved word. To avoid the problem, you should set the QuoteNames option to True. Here is a code example:
Delphi-Quellcode:
uniQuery.Options.QuoteNames := True;

Damit funktioniert es problemlos...

Aber wahrscheinlich muss ich noch aus einem anderen Grund auf die ExecSQL-Variante ausweichen, um anstelle der Delphi-Funktion
Delphi-Quellcode:
Now
die aktuelle Serverzeit einzutragen (über die mySQL-Funktion NOW()). Leider kann ich mir das vorherige Einlesen hier nicht sparen, weil (in der "echten" Anwendung) einige Felder vor dem Update ausgewertet werden müssen...

.sundance.

nahpets 4. Dez 2013 14:53

AW: UniDac Select & Edit (Anfängerfrage)
 
Hallo .sundance.,

stimmt, "index" ist ein reserviertes Wort, da hätte ich auch drauf kommen können :-(

Warum sollte ein
Delphi-Quellcode:
uniQuery.SQL.Text := Format('update %s set spalte1 = %s,
spalte2 = %s, ... spalteN = %s WHERE hostname = %s',[dbTable,wert1,wert2,...,wertN,QuotedString(ComputerName)]);
uniQuery.ExecSql;
komplizierte sein, als ein
Delphi-Quellcode:
    uniQuery.Edit;
    uniQuery.FieldByName('spalte1').AsString := wert1;
    uniQuery.FieldByName('spalte2').AsString := wert2;
     ...
    uniQuery.FieldByName('spalteN').AsString := wertN;
    uniQuery.Post;
?

Querys kann man parametrisieren, schau mal nach ParamByName...

Könnte dann in etwa so aussehen:
Delphi-Quellcode:
uniQuery.SQL.Text := Format('update %s set spalte1 = :spalte1,
spalte2 = :spalt2, ... spalteN = :spalteN WHERE hostname = %s',[dbTable,QuotedString(ComputerName)]);
uniQuery.ParamByName('spalte1').AsString := wert1;
uniQuery.ParamByName('spalte2').AsString := wert2;
...
uniQuery.ParamByName('spalteN').AsString := wertN;
uniQuery.ExecSql;
Und auch hier ist dann nur ein schreibender Zugriff auf die Datenbank notwendig und nicht erst lesen und dann schreiben.

Perlsau 4. Dez 2013 16:42

AW: UniDac Select & Edit (Anfängerfrage)
 
Zitat:

Zitat von sundance (Beitrag 1238503)
INDEX is a MySQL reserved word

Aus diesem Grund habe ich mir bereits vor langer Zeit angewöhnt, die Index-Spalte einer Tabelle stets mit dem Tabellen-Namen zu verbinden, z.B. Idx_Adressen, Idx_Kategorie usw. Nach Möglichkeit sollte man Tabellen- und Spaltennamen mit aussagekräftigen Bezeichnern versehen, um die Lesbarkeit erhöhen. Hat man sich erst einmal an ein bestimmtes Schema gewöhnt, entfällt oft auch das Nachschlagen bzw. Suchen eines Spalten- oder Tabellennamens, denn der ergibt sich dann oft von selbst. Ich weiß also, daß z.B. meine Index-Spalten immer mit Idx_ beginnen und kann so viel flüssiger arbeiten.

sundance 5. Dez 2013 07:35

AW: UniDac Select & Edit (Anfängerfrage)
 
@Frank:
Gute Idee. Hier liegt die Datenbank allerdings gegeben vor, also muss ich mit "index" vorlieb nehmen... Aber beim nächsten Datenbankprojekt soll's dann besser werden.

@Stephan:
OK, "kompliziert" war nicht der richtige Ausdruck.
Was ich meinte war, dass die zeilenweise Zuordnung von Feld und Wert übersichtlicher ist als ein langer SQL-String. Aber das mit "ParameterByName" sieht interessant aus. Werde ich gleich mal probieren.

Ach ja, noch was:
Wie kann man sicher überprüfen, ob nach einem
Delphi-Quellcode:
uniConn.Open
bzw.
Delphi-Quellcode:
uniConn.ExecSQL
die jeweiligen Aktionen fehlerfrei verlaufen sind? Gibt es da bei UniDAC eine Statusabfrage oder wird im Fehlerfall eine Exception ausgelöst?

Vielen Dank für eure Unterstützung
sundance

schlecki 5. Dez 2013 08:21

AW: UniDac Select & Edit (Anfängerfrage)
 
Hi,

ein weiterer Vorteil von ParamByName ist, dass man sich um Quotes und die Konvertierung des Datentyps keine Gedanken machen muss.

jobo 5. Dez 2013 08:24

AW: UniDac Select & Edit (Anfängerfrage)
 
Zitat:

Zitat von Perlsau (Beitrag 1238524)
Aus diesem Grund habe ich mir bereits vor langer Zeit angewöhnt, die Index-Spalte einer Tabelle stets mit dem Tabellen-Namen zu verbinden, z.B. Idx_Adressen, Idx_Kategorie usw. Nach Möglichkeit sollte man Tabellen- und Spaltennamen mit aussagekräftigen Bezeichnern versehen, um die Lesbarkeit erhöhen. Hat man sich erst einmal an ein bestimmtes Schema gewöhnt, entfällt oft auch das Nachschlagen bzw. Suchen eines Spalten- oder Tabellennamens, denn der ergibt sich dann oft von selbst. Ich weiß also, daß z.B. meine Index-Spalten immer mit Idx_ beginnen und kann so viel flüssiger arbeiten.

Diesen Tip halte ich für fragwürdig. Ein Index ist ein "physikalische" Möglichkeit, den Zugriff auf einen Datensatz über bestimmter Felder zu beschleunigen. Welche Felder einen solchen Index besitzen und welche vielleicht einen gemeinsamen Index haben, sollte mit dem Datenmodell und der Benennung nichts zu tun haben.
Wie würdest Du z.B. ein Feld nennen, dass Teil eines Index ist?
Offensichtlich wird gern der Unterschied zwischen Index und Key Constraint vernachlässigt, beides existiert aber technisch völlig unabhängig voneinander und kann auch so eingesetzt werden.

D.h. es ist möglich, eine Primärschlüsselspalte ohne Index zu verwenden (macht natürlich wenig Sinn). Es ist auch möglich einen Index anzulegen, der zu keinem Key Konstraint bzw. logischen Fremdschlüssel gehört. Das macht je nach Anwendungsfall schon sehr viel Sinn und ergibt sich u.U. erst in einer späteren Lebensphase der Datenbank (Tuning).

Feldnamen sollten primär an der Logik des Datenmodells und am Feldinhalt orientiert sein, nicht an physikalischen Gegebenheiten. Die ändern sich nämlich gern mal und dann kann man mit seinen "Konventionen" ganz schön auf dem Bauch landen.
Jedes RDBMS trennt physikalische Optionen (z.B. in der Create Table Anweisung) von den logischen Optionen.

Perlsau 5. Dez 2013 09:02

AW: UniDac Select & Edit (Anfängerfrage)
 
Was soll daran fragwürdig sein? Wenn du beim Datenbank-Design Indexspalten erstellst, die immer automatisch hochgezählt werden, empfiehlt sich diese Vorgehensweise. Wenn du kein eindeutiges Indexfeld erstellst, sondern deinen Index aus mehreren Spalten zusammensetzt, wäre das natürlich Blödsinn. Deshalb jedoch gleich die komplette Idee zu verwerfen, halte ich für mehr als fragwürdig. Hier geht es nicht wirklich um den "Unterschied zwischen Index und Key Constraint", sondern um einen Regelvorschlag zur Benennung ganz bestimmter Spaltentypen. Dein Einwand, daß der Vorschlag bei Konstrukten, für die er gar nicht gedacht ist, nicht funktioniert, ist daher mehr als überflüssig.

jobo 5. Dez 2013 10:36

AW: UniDac Select & Edit (Anfängerfrage)
 
Wenn es um das "Hochzählen" geht, also vielleicht um einen Primärschlüssel(?) und nicht um die Indizierung, warum sollte ich das Feld dann mit dem irreführenden Namensteil "Index" versehen?
Was nützt eine Konvention, wenn sie nicht durchgängig funktioniert? Falls der Name mir eine bestimmte Idee davon geben soll, was die Spalte macht, wie sie sich verhält, warum nennt man es dann nicht genauso. Die Konvention ist in meinen Augen unglücklich, weil Ihre Anwendung nicht in beiden Richtungen Name<>Verhalten durchgängig ist bzw. die Benamung nach Deiner Erläuterung nicht mal etwas mit einem Index zu tun hat.
Der Begriff Index hat in der Datenbankwelt nun mal eine feste Bedeutung. Das wird hier außer Acht gelassen.

p80286 5. Dez 2013 10:42

AW: UniDac Select & Edit (Anfängerfrage)
 
Zitat:

Zitat von Perlsau (Beitrag 1238581)
Was soll daran fragwürdig sein? Wenn du beim Datenbank-Design Indexspalten erstellst,..

Das erinnert mich stark an die alten ISAM-Vorgehensweise. Wenn ich z.B. eine Tabelle mit Personendaten habe käme ich nicht auf die Idee eine Spalte idx_FamilenVorname zu erstellen. Die Indices sind für den schnellen Zugriff auf die Daten notwendig, und wenn für meine Anwendung alle erfassten Daten für den Zugriff genutzt werden, dann gibt es eben für jede Spalte und ggf. für Spaltenkombinationen einen Index.
Wer hier spart, spart am falschen Ende.

Gruß
K-H

Perlsau 5. Dez 2013 12:37

AW: UniDac Select & Edit (Anfängerfrage)
 
Lieber K-H,

ich hatte doch oben bereits deutlich gemacht, daß mein Vorschlag lediglich für jene Fälle gilt, in denen ein automatisch forgezählter oder ein sonstwie erzeugter Index existierst oder notwendig ist. Der TE hatte in seinem Eingangsposting von genau so einer Spalte gesprochen, und genau diesem Fall galt auch mein Vorschlag, den der TE sogar gut findet.

Was du mir hier erzählst, ist mir erstens bekannt und hat mit meinem Vorschlag, wie bereits erwähnt, nichts zu tun. Deshalb verstehe ich nicht, was dich dazu treibt, ständig und wiederholt darauf herumzureiten und meinen Vorschlag der Namensgebung als veraltet, verwirrt, falsch gespart usw. zu diffamieren. Sollte die Ursache in irgend einem Groll gegen mich liegen, darfst du mich gerne via PM darüber aufklären.

Perlsau 5. Dez 2013 12:49

AW: UniDac Select & Edit (Anfängerfrage)
 
Zitat:

Zitat von jobo (Beitrag 1238593)
Wenn es um das "Hochzählen" geht, also vielleicht um einen Primärschlüssel(?) und nicht um die Indizierung, warum sollte ich das Feld dann mit dem irreführenden Namensteil "Index" versehen?
Was nützt eine Konvention, wenn sie nicht durchgängig funktioniert? Falls der Name mir eine bestimmte Idee davon geben soll, was die Spalte macht, wie sie sich verhält, warum nennt man es dann nicht genauso. Die Konvention ist in meinen Augen unglücklich, weil Ihre Anwendung nicht in beiden Richtungen Name<>Verhalten durchgängig ist bzw. die Benamung nach Deiner Erläuterung nicht mal etwas mit einem Index zu tun hat.
Der Begriff Index hat in der Datenbankwelt nun mal eine feste Bedeutung. Das wird hier außer Acht gelassen.

Das ist ein vernünftes Argument, denn tatsächlich ist dein Index in einer Datenbank nicht identisch mit einer AutoInc-Spalte, die z.B. eine Rechnungsnummer oder Personalnummer repräsentiert. Man könnte diese Spalte auch z.B. PK_Adressen nennen oder PK_Rechnung. Ich lehnte mich jedoch bei meiner Namenswahl vor etlichen Jahren, als ich mit dem DB-Design begann, an gängige Vorstellungen an, wonach ein Index (außerhalb der Datenbankwelt) u.a. auch eine zugeordnete willkürliche Nummer sein kann wie z.B. eine Artikelnummer oder Rechnungsnummer. In meinen ersten Access-Datenbanken hießen alle AutoInc-Felder INDEX, wohl auch, weil das in den entsprechenden Tutorials so vermittelt wurde. Davon wird wohl auch der TE bzw. der DB-Designer, der die Datenbank gestaltet hat, mit der der TE nun solche Probleme hatte.

Davon abgesehen wird die PK-Spalte (also jene Spalte, die den Primärschlüssel einer Tabelle stellt) ja sowieso meist indiziert, was die Wahl auf Idx_ als Präfix nicht ganz so absurd erscheinen läßt, wie du es hier darstellst.

Bevor hier jetzt aber wieder Streitigkeiten mit unschönen und an Beleidigungen grenzenden Zuweisungen entstehen, klinke ich mich aus und klicke auf abbestellen. Vielen Dank für's Gespräch.

DeddyH 5. Dez 2013 12:55

AW: UniDac Select & Edit (Anfängerfrage)
 
Ich habe den Thread nun 4 mal komplett durchgelesen und kann nirgends diffamierende Äußerungen entdecken. Im Gegenteil, es wurde mit sehr sachlichen Argumenten dargelegt, dass eine solche Benennung von Spalten evtl. nicht ganz optimal ist, da der Zweck dahinter im Laufe eines Release-Zyklus sehr schnell ad absurdum geführt werden kann. Von daher finde ich diese Reaktion sehr befremdlich :gruebel:

nahpets 5. Dez 2013 13:10

AW: UniDac Select & Edit (Anfängerfrage)
 
Hallo zusammen,

die hier "entstehenden Streit" resultiert vermutlich auf der unterschiedlichen Interpretation von Index.

Frank beschreibt mit Index das, was ich eher unter dem Namen "Technischer Schlüssel" kenne, also eine datenbasierende Möglichkeit der eindeutigen Zuordnung von Daten.

Im Allgemeinen scheint man in der Datenbankwelt unter Index eher die technische Möglichkeit des schnellen Zugriffes auf Daten zu verstehen, eine Eindeutigkeit ist hier nicht zwingend erforderlich. Diese technische Möglichkeit dürfte datenbankabhängig sein und dient ausschließlich der schnelleren Verarbeitung von Daten, kann/muss daher außerhalb der dateninduzierten liegen.
In meiner bisherigen ca. 25-jahrigen Praxis mit vielen Unternehmen und Kunden ist mir kein Fall erinnerlich, in dem mit dem Begriff Index nicht die technische Möglichkeit des optimierten Datenzugriffs seitens der Datenbank gemeint war.

Sicherlich ist es "im realen Leben" sinnvoll, technische Schlüssel mit einem Index zu versehen. Um die Eindeutigkeit eines technischen Schlüssels sicherzustellen, empfiehlt sich ein eindeutiger Index (Primary Key). Ein AutoInc-Feld bildet diese Eindeutigkeit auf einem anderen Weg ab.

Eventuell sollten wir bei der Benutzung des Wortes Index hinzufügen, ob wir die technische Variante oder die dateninduzierte Variante meinen. Hierdurch ließen sich die "Streitigkeiten" bzw. "Missverständnisse" sicherlich deutlich reduzieren.

sx2008 5. Dez 2013 17:06

AW: UniDac Select & Edit (Anfängerfrage)
 
Also ich mache das so:
Alle Primärschlüsselfelder und alle Fremdschlüsselfelder erhalten den Prefix Id (z.B. IdCustomer, IOrder, IdArticle,...).
Eine SQL-Abfrage sieht dann z.B. so aus
SQL-Code:
SELECT [feldliste]
FROM Orders INNER JOIN Customer ON Orders.IdCustomer=Customer.IdCustomer
-- Customer.IdCustomer ist ein Primärschlüsselfeld
-- Orders.IdCustomer ist ein Fremdschlüsselfeld mit gleichem Datentyp&Länge
Felder auf denen ein (oder mehrere)Index liegt (z.B. PLZ, OrderDate, CountryCode, ...) bleiben unverändert.
Feld- und Tabellennamen schreibe ich in UpperCamelCase.
Erlaubt sind nur Buchstaben, Ziffern und der Unterstrich; max 32 Zeichen.
Keine deutschen Umlaute oder Bezeichner die mit einer Ziffer beginnen.
Im Prinzip die gleichen Regeln, die auch für Pascal Bezeichner gelten.

Was sich nicht bewährt hat ist:
* Fester Prefix für alle Felder z.B. alle Feldnamen mit beginnen mit F und alle Tabellennamen beginnen mit T
* Feldnamen werden aus Tabellenname + "_" + Feldname zusammengesetzt wie z.B. (Bestellung_Datum, Customer_City)

Ich habe ein Programm mit dem ich grundsätzlich alle Namen auf reservierte Wörter überprüfe.
Dabei werden nicht nur reservierte Wörter der aktuell verwendeten Datenbank angemeckert sondern auch von anderen Datenbankherstellern.
Damit wird verhindert dass es in Zukunft Probleme gibt falls das Schema mal auf ein anderes DBMS portiert werden sollte.
http://support.microsoft.com/default...b;en-us;321266
http://docs.oracle.com/cd/B19306_01/...rved_words.htm
http://developer.mimer.com/validator...rved-words.tml
http://www.firebirdsql.org/refdocs/l...-reswords.html

jobo 5. Dez 2013 17:13

AW: UniDac Select & Edit (Anfängerfrage)
 
Eigentlich gehört das wohl nicht hier her, den Thread relevanten Teil hat sx2008 mit seinen Hinweisen zu den reservierten Wörtern geliefert.
Trotzdem mein Senf zum Thema Index & Co. Auch wenn es mehr oder weniger bekannt sein dürfte, vielleicht hilft es jemand weiter, für absurd halte ich es jedenfalls nicht.

Constraints
===========
Constraint, eine Regel in einem RDBMS, die verschiedene Ausprägungen haben kann und sich z.B. auf einen einzelnen Spaltenwert oder alle Werte einer Spalte oder mehrere Spalten beziehen kann.

Primary Key Constraint, eine spezielle Constraint Form, die bezüglich ein oder mehrerer Spalten Eindeutigkeit und „nicht undefiniert“ fordert. Die Erzeugung der Werte erfolgt häufig über AutoInc Datentypen, Trigger oder Trigger & Generatoren/Sequenzen datenbankseitig, clientseitig dagegen mittlerweile häufig über GUID oder UUID.

Eine Spalte mit Primary Key Constraint wird häufig als Primärschlüssel übersetzt. Es kann auch Sekundärschlüssel geben, also weitere Spalten, die ebenfalls einen eindeutigen Zugriff erlauben.

Unique Constraint, wie Primary Key, „undefiniert“ jedoch erlaubt.

Foreign Key Constraint definiert die Existenz identischer Feldwerte in einer anderen Spalte (einer anderen Tabelle).
Es gibt weitere Constraint Formen.

Ein Datenmodell kann angelegt werden, ohne einen dieser Constraints zu verwenden. Damit lässt man allerdings wesentliche Merkmale eines RDBMS ungenutzt, was Folgen hat für Exaktheit bzw. Konsistenz und Robustheit der Datenverarbeitung. Sind diese und andere Constraints definiert, so garantiert(!) ein echtes RDBMS die Einhaltung u.a. dieser Constraint Regeln (siehe ACID).
Ich habe bereits Software gesehen, die auf derartigen Datenmodellen ohne Constraints aufsetzt. Der Sinn erschließt sich mir nicht, in Betracht kommen Ahnungslosigkeit, Schlamperei, Faulheit oder der Versuch von Obfuscation.

Indizes
=======
Indizes haben mit Constraints nichts zu tun, sie beschleunigen idealer Weise nur den Datenzugriff. Damit helfen sie allerdings dem RDBMS, die definierten Constraints möglichst leicht (also schnell) einzuhalten.

Der Index ist eine zusätzliche, physikalisch vorhandene Sortierung der Feldinhalte ein oder mehrerer Spalten, ein Index kann dabei ebenfalls die Eigenschaft „unique“ beinhalten. Die Sortierungsmöglichkeiten bzw. der Indexaufbau kann je nach RDBMS verschiedene Möglichkeiten bieten, bspw. als Bitmap Index oder Function Based Index. Außerdem können Indizes auch mehrfach auf identischen Spalten angelegt werden. Falls das nicht versehentlich geschieht: es wird absichtlich evtl. zur Indexreorganisation verwendet, ansonsten verlangsamt es lediglich Einfügen und Ändern von Daten weiter, wie jeder Index.

Indizes haben gar nichts mit Funktionsweise und Logik des Datenmodells zu tun und können gelöscht werden, ohne der Funktion eines Datenmodells (ACID) zu schaden. Es wird lediglich langsamer.
(Ich schließe hier mal extra nicht aus, dass es herstellerabhängige Sonderformen gibt, wo das Löschen eines Index auch die Funktion beeinträchtigt.)

Indizes haben eigene Namen, die allerdings häufig vom DB System vergeben werden, z.B. im Falle einer Spalte, die mit Primary Key Constraint definiert wurde, ohne die Indexoptionen explizit anzugeben.

Umgang mit Indizes im Client
============================
Da sie nichts zum Datenmodell an sich beitragen, können sie z.B. auch in separaten Skripten verwaltet werden. Wegen Ihrer Unbeständigkeit, ist es auch nicht zu empfehlen, clientseitig Indizes namentlich anzusprechen (außer das Programm dient der Indexverwaltung bzw. erzeugt oder ändert seine eigene DB „on the fly“).
Ebenso ist es nicht empfehlenswert, Existenz und Art des Index in Spaltenbenennung einzubeziehen. Das gilt auch für alle anderen physikalischen Optionen einer Datenbank. Dieser Teil hat erhebliche Bedeutung bei der so angesagten datenbankunabhängigen Programmierung. SQL Syntax für Indexdefinition ist kaum standardisiert, Datenmodelle mit eingestreuten Index Statements sind also schwerer zu migrieren.

p80286 5. Dez 2013 17:51

AW: UniDac Select & Edit (Anfängerfrage)
 
Zitat:

Zitat von sx2008 (Beitrag 1238676)
Was sich nicht bewährt hat ist:
* Fester Prefix für alle Felder z.B. alle Feldnamen mit beginnen mit F und alle Tabellennamen beginnen mit T
* Feldnamen werden aus Tabellenname + "_" + Feldname zusammengesetzt wie z.B. (Bestellung_Datum, Customer_City)

Warum?
Code:
select TName.FName, FVorname
from TName
gefällt mir zwar nicht aber kommt allen entgegen die sich gerne um qualifizierte Namen drücken.

Bestellungen.BestellDatum,Zahlung.ZahlungsEingangs datum;Bestellungen.BestellEingangsdatum
vs
Bestelldatum,ZahlungsEingangsdatum,BestellEingangs datum
vs
Bestellungen.Datum,Zahlung.Eingangsdatum,Bestellun gen.Eingangsdatum

"Schöner" finde ich die dritte Möglichkeit, in der Praxis habe ich mit der ersten zu tun und nach einer unschönen Eingewöhnungsphase kann ich damit gut umgehen, da zumindestens ich immer weiß wo ich gerade bin.

Gruß
K-H

Perlsau 5. Dez 2013 18:33

AW: UniDac Select & Edit (Anfängerfrage)
 
Zitat:

Zitat von nahpets (Beitrag 1238635)
Sicherlich ist es "im realen Leben" sinnvoll, technische Schlüssel mit einem Index zu versehen. Um die Eindeutigkeit eines technischen Schlüssels sicherzustellen, empfiehlt sich ein eindeutiger Index (Primary Key). Ein AutoInc-Feld bildet diese Eindeutigkeit auf einem anderen Weg ab. Eventuell sollten wir bei der Benutzung des Wortes Index hinzufügen, ob wir die technische Variante oder die dateninduzierte Variante meinen. Hierdurch ließen sich die "Streitigkeiten" bzw. "Missverständnisse" sicherlich deutlich reduzieren.

Dem stimme ich zu, insbesondere auch deinen Ausführungen über die Verwendung des Begriffs "Index" im Umfeld von Datenbank-Design und -Entwicklung. Mir ging es jedoch nicht darum, unbedingt das Präfix "Idx_" hervorzuheben, sondern auf die allgemeine Möglichkeit, mit einem sinnvollen Präfix zu vermeiden, geschützte Bezeichner zu verwenden, hinzuweisen. Ließe man das x weg, ergäbe sich daraus das sinnvollere Präfix "Id_", um eindeutige ID-Spalten zu benennen. Bei mehreren ähnlichen Tabellen in derselben Datenbank oder beim Erstellen von Views gehe ich ähnlich vor, indem ich aus dem Tabellennamen ein Präfix ableite und das den Spaltennamen voranstelle. Mir hat das immer sehr geholfen, weil ich allein durch Logik auf gesuchte Bezeichner kam und nicht erst nachschauen mußte (die dritte Alternative wäre Auswendiglernen).

In der Tat hatte mich die Verwendung des Präfixes "Idx_" jedoch nie in Verwirrung gestürzt, weil ich niemals auf die Idee verfallen wäre, im Spaltennamen einen Bezeichner für das Resultat einer Indizierung zu vermuten. Ich würde auch nicht auf die Idee kommen, die Bezeichnung "Hahn" in einer Installationsfirma mit einem Federvieh in Verbindung zu bringen oder in einem Schreibwarengeschäft die Bezeichnung "Feder" mit dem "Kleid" eines Hahns. Allergings kommen in Schreibwarengeschäften schon zwei grundveschiedene Federn vor, nämlich die im Füllfederhalter und die im Kugelschreiber. Aber das ist wohl eine andere Geschichte ...


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:11 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