![]() |
Datenbank: Firebird • Version: 2.1.2.18118-0 • Zugriff über: InterBase
Datenbank Primary Key
Hey ;)
Ich beschäftige mich zur Zeit mit Datenbanken und habe hier auch einiges über Primary Key und doppelten Einträgen gelesen, jedoch bleibt jetzt noch eine Frage offen: In wie fern ist der Primary Key gut um Duplikate auszuschließen: (FELD1 soll keine Duplikate enthalten) Ich lege den PK auf das Feld1. Jetzt füge ich den Wert "TEST" hinzu. Danach füge ich den Wert "test" hinzu. Beide Werte wurden erfolgreich hinzugefügt. Nur wenn ich erneut versuche "TEST" oder "test" hinzuzufügen dann bekomme ich eine Fehlermeldung auf Grund des Duplikats. Wie kann ich das ganze Case Insensitive gestalten ? Ich möchte das mein DBMS keinen Unterschied zwischen Groß- und Kleinschreibung macht.
Code:
bYe :)
CREATE TABLE MYTABLE(FELD1 varchar(30) PRIMARY KEY, FELD2 varchar(30));
|
AW: Datenbank Primary Key
|
AW: Datenbank Primary Key
Das Thema habe ich bereits gelesen und nein, ehrlich gesagt finde ich da keine Lösung für mich.
|
AW: Datenbank Primary Key
![]() |
AW: Datenbank Primary Key
Das hört sich irgendwie nach "Workaround" an und du selber sagst ja das es ab FB 2.1 nicht mehr notwendig ist... Also will ich nicht zu Anfang schon tricksen ;)
Ich könnte auch einfach meine Einträge auf ein Niveau bringen bevor ich sie hinzufüge aber das wäre auch nur ein Workaround .. bYe :) |
AW: Datenbank Primary Key
Nunja, andererseits nehme ich persönlich lieber einen zuverlässig funktionierenden Workaround, als tagelang nach einer "sauberen" Lösung zu suchen. Außerdem würde ich persönlich kein VarChar-Feld als PK definieren (obwohl das natürlich nicht verboten oder verwerflich ist), sondern immer ein künstliches Feld, das per Generator-/Trigger-Paar automatisch befüllt wird. Aber das ist sicher Ansichtssache.
|
AW: Datenbank Primary Key
Hmm naja also ich möchte in diesem Feld keine Duplicates also hab ich das als PK definiert.
Kann man einem Feld nicht eine Case Eigenschaft verpassen ? |
AW: Datenbank Primary Key
Vielleicht hilft Dir
![]() |
AW: Datenbank Primary Key
Hm ich dachte der Expression Index spielt nur bei einer Abfrage eine Rolle ? Ich frage ja nicht ab ob Duplicates vorhanden sind, das macht das DBMS von selber. ..Oder hab ich das falsch verstanden ?
|
AW: Datenbank Primary Key
Hi!
Du kannst auch Duplikate verhindern, ohne dass es sich bei diesem Feld um den PK handelt. Das Zauberwort ist UNIQUE. Vor allem kannst du auch mehrere UNIQUE-Felder haben, aber nur einen PK. Aber auch UNIQUE ist von Haus aus case-sensitive. Grüße, Frederic |
AW: Datenbank Primary Key
Hm und welche Funktion hat dann der PK ? Also klar "die Daten sind dann leichter abrufbar" aber kann da jemand genauer drauf eingehen ? Hat das was mit der "Binären Suche" zu tun ?
Und zum Problem: Also es gibt keine Möglichkeit einem Feld die Eigenschaft CASE INSENSITIVE zu verschaffen ? |
AW: Datenbank Primary Key
Der PK ist wie der Name sagt, ein Schlüssel - ein Schlüssel dient dazu, ein Tupel in einer Tabelle eindeutig zu identifizieren.
Dabei gibt es verschiedene Konzepte - ein Superschlüssel erfüllt einfach das o.g. - ein sog. Kandidatenschlüssel erfüllt das auch, ist aber zusätzlich minimal - d.h. man kann ihn nicht mehr kleiner machen, ohne, dass er nicht mehr Schlüssel wäre. So, der primary key schlussenndlich ist ein an sich beliebig ausgewählter Kandidatenschlüssel. Besondere Bedeutung bekommt er, wenn es um Fremdschlüssel-zuweisungenn gibt... Grüße, Frederic |
AW: Datenbank Primary Key
Als Primary key kannst Du eine beliebige Kombination von Feldern definieren, einzige Voraussetzung ist, dass diese Feldkombination jeden Datensatz eindeutig identifiziert. Zum Primary key legt das DBS automatisch einen Index an, der natürlich Unique ist. In der Praxis empfiehlt es sich UNBEDINGT, in JEDER Tabelle ein künstliches, Trigger-befülltes Feld zu definieren, das Du als Primary Key hernimmst. Jede andere Vorgangsweise führt mit ziemlicher Sicherheit früher oder später zu Problemen.
Zusätzlich zum Primary key, für den das DBS automatisch einen Unique Index anlegt, kannst Du nach beliebige andere Indexe (oder sagt man Indizes?) anlegen, die den Zugriff auf die Datenbank über die entsprechenden Feldelemente beschleunigen. Ist so ein Index als Unique definiert, dann erlaubt das Datenbanksystem keine 2 Datensätze mit identischen Feldwerten in diesen Feldern. Der Unique Index kann auch berechnet sein, so kannst Du einen Unique Index auf UPPER(Feld) legen und damit eine Case-insensitive Feldeindeutigkeit erzwingen. Die Eindeutigkeit des Zugriffs an einen Index zu koppeln, ist insofern sinnvoll, als ohne vorhandenen Index die Überprüfung auf Eindeutigkeit extrem langsam wäre. Aber im Prinzip dient der Index in erster Linie zum schnellen Auffinden von Datensätzen und quasi nur als Nebeneffekt kann über einen UNIQUE Index Eindeutigkeit erzwungen werden. Das Problem eines berechneten Unique Index ist, dass er nur vor dem Speichern von Duplicates schützt, beim Zugriff auf die Daten aber nicht verwendet wird. Wenn Du also irgendwo in einer Abfrage des Feldes auf =, <, >, like oder dergleichen abfragst, ist diese Abfrage erst wieder case-sensitiv und liefert Dir das gewünschte Ergebnis nur, wenn Du Upper(Feld) mit Upper(Vergleichswert) vergleichst. Seit Firebird 2 ist es aber problemlos möglich, einem Feld eine caseinsensitive (und sogar eine accent insensitive) "Collation" zuzuordnen. Damit wird sozusagen das Feld selbst caseinsensitiv gemacht. Wenn Du das machst, wird automatisch überall, wo der Inhalt des Feldes mit etwas anderem verglichen wird, ein Case-insensitiver Vergleich durchgeführt. Es gibt standardmässig in Firebird zwar nur ganz wenige case-insensitive Collations, aber es ist sehr einfach, eine solche zu definieren - siehe ![]() Die Verwendung von Uppercase-Schattenfeldern in der Datenbank war früher der einzig mögliche Workaround, weil es damals mit den Möglichkeiten der Datenbanksysteme nicht anders ging, hat aber heute bei einer Datenbankneuentwicklung überhaupt nichts verloren. |
AW: Datenbank Primary Key
Zitat:
Stell' Dir vor, du hast eine Tabelle in der einige Datensätze völlig gleich sind:
Code:
Dich stört der doppelte Datensatz; du willst ihn löschen.
FeldA | Feld B | Feld C
======================= 430 | 14.70 | blau 590 | 20.00 | rot 430 | 14.70 | blau Mit SQL gibt es aber keine Chance nur einen der beiden Datensätze zu löschen. Das gleiche Problem entsteht beim Editieren. Über eine UPDATE-Anweisung würden immer beide Datensätze geändert. Nur wenn eine Tabelle einen PK hat, kann garantiert werden, dass jeder Datensatz einzeln ansprechbar ist. |
AW: Datenbank Primary Key
Außerdem kommt der PK noch bei Detailtabellen zum Tragen. Hier muss der Master-Datensatz ja eindeutig identifizierbar sein.
|
AW: Datenbank Primary Key
Der Primary key ist aber nichts anderes als ein willkürlich ausgewählter eindeutiger Schlüssel. Wenn Du die Datensätze über unterschiedliche Schlüssel eindeutig identifizieren kannst, dann kannst Du theoretisch jede beliebige Kombination von Feldern, die die Datensätze eindeutig identifizieren, zum primary key ernennen. Früher hab ich das gelegentlioch so gehandhabt, es ist mir aber noch jedesmal später auf den Kopf gefallen. Deshalb die Empfehlung, als Primary Key prinzipiell ein künstliches Feld zu verwenden, das mit Hilfe eines insert-Triggers und eines Generators (neuerdings heisst das auch in Firebird - SQL Standard gemäss - Sequence) gesetzt wird.
|
AW: Datenbank Primary Key
Das hat ja auch niemand bestritten. Ich persönlich verzichte allerdings gelegentlich auf einen Generator, wenn es sich um eine Auflösungstabelle einer m:n-Beziehung handelt. In dem Fall kann man IMO auch getrost die Kombination der beiden FKs als PK definieren. Wobei es natürlich auch nicht schadet, auch hier einen künstlichen Schlüsel zu erzeugen und die angesprochene Kombination einfach UNIQUE zu deklarieren. Wie man sieht gibt es hier mehrere Möglichkeiten.
|
AW: Datenbank Primary Key
Ja, Du hast schon Recht. Wenn es sich nur um eine Auflösungstabelle einer m:n-Beziehung handelt, könnte man sich das künstliche Feld samt Trigger wahrscheinlich sparen.
|
AW: Datenbank Primary Key
Er schadet aber nicht und ermöglicht eine spätere Erweiterung
|
AW: Datenbank Primary Key
Hm okay eine Sache ist noch unklar.
Wenn ich ein Feld_A habe und dieses als PK definieren will dann soll ich ein künstliches K_Feld_A erzeugen und einen Trigger auf das eigentliche Feld_A setzen. Danach kann ich K_Feld_A als PK definieren. Und was soll das ganze ? Warum definiert man nicht gleich das Feld_A als PK ? |
AW: Datenbank Primary Key
Hi!
Du sollst keinen Trigger auf Feld_A setzen. Ein Trigger ist einfach eine Funktion, die z.B. bei jedem Insert aufgerufen wird (in dem Fall hier vor dem Insert - ein sog. before-Trigger) Machen wir mal ein prakt. Beispiel: Du hast eine Tabelle "Adressdaten" mit den Feldern "Strasse, Hausnummer, PLZ, Ort, Land" - nach den Anforderungen deines Systems sind alle diese Felder nötig, um eine Adresse eindeutig zu identifizieren. Du müsstest also einen PK definieren, der über alle 5 Felder geht. (Würdest du z.B. nur Strasse+Hausnummer nehmen würden diese 2 Einträge nicht gehen: "Hauptstr., 22, 12345, Testort, Testland" und "Haupstr., 22, 98765, Musterstadt, Musterland". Somit hast du jetzt einen ziemlich unhandlichen PK in der Hand. Sagen wir mal, du hast eine Tabelle Person [Vorname, Nachname] (auch beide zusammen als PK) und willst der Person eine Adresse zuordnen - das Ganze als n:m-Beziehung (also mehrere Personen an einer Adresse, mehrere Adressen pro Person), dann musst du in der Tabelle, die diese Beziehung ausdrückt, die Schlüssel der beiden beteiligten Tabellen haben. D.h. du hast hier eine Mega-Tabelle mit 7 Attributen. So, würdest du sowohl bei Person wie auch bei Adresse einen künstlichen PK erzeugt hast (fortlaufende Nummerierung), dann identifiziert das eindeutig. D.h. du brauchst in der Beziehunstabelle nur 2 Felder, die ID von Person und die ID von Adresse. Ich hoffe, ich konnte etwas Licht ins Dunkle bringen. ;) Liebe Grüße, Frederic |
AW: Datenbank Primary Key
Jo alles klar das hab ich kapiert :)
Nochmal zu der Frage "Warum lassen sich Daten mit einem PK schneller abrufen?" : Das macht doch nur Sinn wenn in der Abfrage der abzurufende Schlüssel bekannt ist ? |
AW: Datenbank Primary Key
Das zusätzlich Feld wird zum PK. Das hat den Vorteil, dass die Werte im FELD_A später geändert werden können ohne dass Fremdschlüsselbeziehung zerstört werden bzw. angepasst ´werden müssten.
|
AW: Datenbank Primary Key
Es geht da nicht um "schneller".
Der PK muß Unique sein. Auch wenn im Moment iregend eine Feldkombination unique ist, muß das nicht immer so bleiben. Beispiel: Du hast einen Unique Key: Name, Vorname, Wohnort. Dein Programm funktioniert wunderbar, und greifst überall in Deinem Programm mit diesem primary Key auf die Tabelle zu. Jetzt kommst Du irgendwann drauf, dass es in Berlin zwei verschiedene Hans Meier gibt, die Du in Deiner Datenbank verwalten musst, und brauchst deshalb für die Eindeutigkeit noch zusätzlich das Feld Strasse. Dann musst Du überall in Deinem Programm in allen Abfragen den Zugriff auf die Datenbank anpassen, alle Fremdschlüssel, die in anderen Tabellen auf diese Tabelle verweisen, müssen geändert werden usw. Wenn Du aber von vorneherein ein künstliches Feld als PK verwendest, bedeutet so eine Änderung nur minimalen Aufwand. |
AW: Datenbank Primary Key
Zitat:
Szenario 1 (ohne IDs) : folgende Tables werden für irgendein Programm gebraucht : Artikel, Lager, Statistik, Rechnung. Den 3 letzten müssen dann natürlich Artikel zugeordnet werden. OK, man nimmt die Art.Nr. Da stehen also jetzt in der Lager-,Statistik- und Rechnungstabelle z.B. Datensätze mit artnr = 100. Der User verspürt aber plötzlich Lust, für den entsprechenden Artikel artnr = 1000 zu verwenden. Was ist zu tun ? Die 3 vom Artikel abhängigen Tabellen müssen komplett nach artnr = 100 durchsucht werden und an allen Fundstellen durch artnr = 1000 ersetzt werden. Im Prinzip kann erst wenn alle auf 1000 gesetzt sind der entsprechende Artikel selbst von artnr = 100 auf 1000 geändert werden. Szenario 2 (mit IDs) : Artikel kriegt zusätzlich eine ID. Und diese wird automatisch per Generator/Trigger hochgezählt. Dann ist sie sofort eindeutig. Auch die drei anderen Tabellen erhalten vorsichtshalber eine ID und auch (und jetzt kommt das Wichtige) eine IDart. Also steht da nicht mehr ein Feld artnr = 100, sondern das Feld IDart = 95 (bspw.). Die 95 stammt von dem Artikel mit Nr. 100, der die ID = 95 hat. Was muss hier jetzt bei Änderung der Art.Nr. von 100 auf 1000 gemacht werden ? Einfach das Feld Art.Nr. von 100 auf 1000 ändern. Das wars. Die 95 bleibt ja, wie sie ist. Für die Rechnung- usw. Tabellen, ist der Artikel dadurch immer noch eindeutig zu lokalisieren. Da braucht überhaupt nichts gemacht zu werden ! Man sieht hier sehr oft weggelassene IDs oder so was wie bereits gesagt : PK für Name und dann noch die Str. mitschleppen usw. Was aber, wenn in einem Haus 2 Meier wohnen ? Ich sage nur : Murphy lässt grüssen. :mrgreen: Mal ganz davon abgesehen, dass ein PK aus Name, Strasse, Ort oder womöglich noch mehr viel zu gross wird. ID hätte lediglich 4 Byte. :gruebel: |
AW: Datenbank Primary Key
Ja, wie schon erwähnt...das hab ich kapiert.
Ich war nur etwas verwirrt weil, anscheinend ein labersack, mal meinte "wenn du kein pk hast, dann wird es Ewigkeiten dauern einen String in deinem Feld zu finden" ... |
AW: Datenbank Primary Key
Wenn die Tabelle sehr groß ist, kann es schon dauern, wird dieses Feld dann zufällig zum PK, kann es schon schnneller werden ( wenn nicht auf like gesucht wird). Ich glaube aber er hat PK mit Index verwechselt/gleichgesetzt
|
AW: Datenbank Primary Key
Hm ja möglicherweise. Aber auf einen Primärschlüssel wird doch automatisch ein Index gelegt? Möglicherweise hat er das verwechselt.
|
AW: Datenbank Primary Key
Jedes PK-Feld wird automatisch indiziert, aber nicht jedes indizierte Feld wird automatisch PK (wie soll das auch funktionieren?).
|
AW: Datenbank Primary Key
Ja, das hat auch keiner behauptet ;) Ich denke ich habe vorerst genug Informationen.. Danke !
bYe |
AW: Datenbank Primary Key
Zitat:
Mich wundert übrigens, dass hier noch nicht das Wort ![]() |
AW: Datenbank Primary Key
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:32 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz