Κύριο κλειδί και Ξένο κλειδί in SQLite με παραδείγματα

⚡ Έξυπνη Σύνοψη

Πρωτεύοντα κλειδιά και ξένα κλειδιά σε SQLite Ενισχύστε την ακεραιότητα των δεδομένων προσδιορίζοντας μοναδικά κάθε γραμμή και συνδέοντας σχετικούς πίνακες, διασφαλίζοντας ότι οι τιμές αναφοράς υπάρχουν πάντα και αποτρέποντας διπλότυπες, μηδενικές ή ορφανές εγγραφές σε μια σχεσιακή βάση δεδομένων.

  • 🔑 Πρωτεύων κλειδί: Ένα πρωτεύον κλειδί προσδιορίζει μοναδικά κάθε γραμμή και οι τιμές του πρέπει να είναι μοναδικές και ποτέ null.
  • 🧩 Σύνθετο Κλειδί: Ο συνδυασμός δύο ή περισσότερων στηλών σχηματίζει ένα σύνθετο πρωτεύον κλειδί όταν καμία μεμονωμένη στήλη δεν είναι μοναδική.
  • 🔗 Ξένο κλειδί: Ένα ξένο κλειδί αναφέρεται σε ένα γονικό κλειδί πίνακα και επιβάλλει την ακεραιότητα αναφορών μεταξύ των σχετικών πινάκων.
  • ⚙️ Ενεργοποίηση Επιβολής: SQLite απενεργοποιεί τα ξένα κλειδιά από προεπιλογή, επομένως εκτελέστε την εντολή PRAGMA foreign_keys = ON για να τα ενεργοποιήσετε.
  • 🧱 Περιορισμοί στηλών: Οι κανόνες NOT NULL, DEFAULT, UNIQUE και CHECK επικυρώνουν τις τιμές πριν εισέλθουν σε μια στήλη.
  • 🤖 Βοήθεια AI: Οι βοηθοί μετατροπής κειμένου σε SQL με τεχνητή νοημοσύνη και το GitHub Copilot δημιουργούν SQL κλειδιών και περιορισμών από απλά αγγλικά.

Κύριο κλειδί και Ξένο κλειδί in SQLite

Οι παρακάτω ενότητες εξηγούν SQLite περιορισμοί λεπτομερώς, ξεκινώντας με το ΠΡΩΤΕΥΟΝ ΚΛΕΙΔΙ και το ΞΕΝΟ ΚΛΕΙΔΙ που ορίζουν και συνδέουν πίνακες, και καλύπτοντας τους κανόνες NOT NULL, DEFAULT, UNIQUE και CHECK που επικυρώνουν τα δεδομένα σε κάθε στήλη.

SQLite Περιορισμοί

Οι περιορισμοί στηλών επιβάλλουν κανόνες στις τιμές που εισάγονται σε μια στήλη, προκειμένου να επικυρωθούν τα δεδομένα. Αυτοί οι περιορισμοί ορίζονται κατά τη δημιουργία ενός πίνακα, μέσα στον ορισμό της στήλης. Διατηρούν τα αποθηκευμένα δεδομένα συνεπή και ακριβή, απορρίπτοντας τιμές που παραβιάζουν τους κανόνες που ορίζετε, όπως διπλότυπα, null ή τιμές που δεν υπάρχουν σε έναν σχετικό πίνακα.

SQLite Πρωτεύων κλειδί

Όλες οι τιμές σε μια στήλη πρωτεύοντος κλειδιού πρέπει να είναι μοναδικές και όχι null. Το πρωτεύον κλειδί προσδιορίζει μοναδικά κάθε γραμμή στον πίνακα.

Το πρωτεύον κλειδί μπορεί να εφαρμοστεί μόνο σε μία στήλη ή σε έναν συνδυασμό στηλών. Στην τελευταία περίπτωση, ο συνδυασμός των τιμών των στηλών θα πρέπει να είναι μοναδικός για όλες τις γραμμές του πίνακα.

Σύνταξη:

Υπάρχουν διάφοροι τρόποι για να ορίσετε ένα πρωτεύον κλειδί σε έναν πίνακα:

Στον ίδιο τον ορισμό της στήλης:

ColumnName INTEGER NOT NULL PRIMARY KEY;

Ως ξεχωριστός ορισμός:

PRIMARY KEY(ColumnName);

Για να δημιουργήσετε έναν συνδυασμό στηλών ως πρωτεύον κλειδί:

PRIMARY KEY(ColumnName1, ColumnName2);

SQLite Περιορισμοί NOT NULL, DEFAULT, UNIQUE και CHECK

Εκτός από το πρωτεύον κλειδί, SQLite παρέχει αρκετούς περιορισμούς στηλών που επικυρώνουν τις τιμές που εισάγονται σε έναν πίνακα. Οι περιορισμοί NOT NULL, DEFAULT, UNIQUE και CHECK ορίζονται ο καθένας στον ορισμό της στήλης και ο καθένας από αυτούς επιβάλλει έναν συγκεκριμένο κανόνα στη στήλη. Τύπος δεδομένων και αξίες.

NOT NULL Περιορισμός

The SQLite Ο περιορισμός NOT NULL εμποδίζει μια στήλη να έχει μια τιμή null:

ColumnName INTEGER  NOT NULL;

Προεπιλεγμένος περιορισμός

Με την SQLite Με τον περιορισμό DEFAULT, εάν δεν εισαγάγετε καμία τιμή σε μια στήλη, εισάγεται η προεπιλεγμένη τιμή.

Για παράδειγμα:

ColumnName INTEGER DEFAULT 0;

Εάν γράψετε μια εντολή insert και δεν καθορίσετε καμία τιμή για αυτήν τη στήλη, η στήλη θα έχει την τιμή 0.

Μοναδικός περιορισμός

The SQLite Ο περιορισμός UNIQUE αποτρέπει τις διπλότυπες τιμές μεταξύ όλων των τιμών της στήλης.

Για παράδειγμα:

EmployeeId INTEGER NOT NULL UNIQUE;

Αυτό επιβάλλει στην τιμή "EmployeeId" να είναι μοναδική. Δεν επιτρέπονται διπλότυπες τιμές. Σημειώστε ότι αυτό ισχύει μόνο για τις τιμές της στήλης "EmployeeId".

Ελέγξτε τον περιορισμό

The SQLite Ο περιορισμός CHECK ορίζει μια συνθήκη για τον έλεγχο μιας εισαγόμενης τιμής. Εάν η τιμή δεν ταιριάζει με τη συνθήκη, δεν θα εισαχθεί.

Quantity INTEGER NOT NULL CHECK(Quantity > 10);

Δεν μπορείτε να εισαγάγετε τιμή μικρότερη από 10 στη στήλη "Ποσότητα".

SQLite Ξένο κλειδί

The SQLite Ένα ξένο κλειδί είναι ένας περιορισμός που επαληθεύει την ύπαρξη μιας τιμής που υπάρχει σε έναν πίνακα σε έναν άλλο πίνακα που έχει μια σχέση με τον πρώτο πίνακα όπου ορίζεται το ξένο κλειδί.

Κατά την εργασία με πολλούς πίνακες, υπάρχουν περιπτώσεις όπου δύο πίνακες σχετίζονται μεταξύ τους μέσω μίας κοινής στήλης. Εάν θέλετε να διασφαλίσετε ότι η τιμή που εισάγεται σε έναν από αυτούς πρέπει να υπάρχει στη στήλη του άλλου πίνακα, τότε θα πρέπει να χρησιμοποιήσετε έναν περιορισμό ξένου κλειδιού στην κοινή στήλη.

Σε αυτήν την περίπτωση, όταν προσπαθείτε να εισαγάγετε μια τιμή σε αυτήν τη στήλη, το ξένο κλειδί θα διασφαλίσει ότι η εισαγόμενη τιμή υπάρχει στη στήλη του πίνακα αναφοράς.

Σημειώστε ότι οι περιορισμοί ξένου κλειδιού δεν είναι ενεργοποιημένοι από προεπιλογή στο SQLiteΠρέπει πρώτα να τα ενεργοποιήσετε εκτελώντας την ακόλουθη εντολή:

PRAGMA foreign_keys = ON;

Εισήχθησαν περιορισμοί εξωτερικού κλειδιού SQLite ξεκινώντας από την έκδοση 3.6.19.

Παράδειγμα SQLite Ξένο κλειδί

Ας υποθέσουμε ότι έχουμε δύο πίνακες: Φοιτητές και Τμήματα.

Ο πίνακας "Φοιτητές" περιέχει μια λίστα φοιτητών και ο πίνακας "Τμήματα" περιέχει μια λίστα των τμημάτων. Κάθε φοιτητής ανήκει σε ένα τμήμα, δηλαδή, κάθε φοιτητής έχει μια στήλη "departmentId".

Τώρα θα δούμε πώς ο περιορισμός ξένου κλειδιού μπορεί να είναι χρήσιμος για να διασφαλιστεί ότι η τιμή του αναγνωριστικού τμήματος στον πίνακα Φοιτητές πρέπει να υπάρχει στον πίνακα Τμήματα.

Έτσι, αν δημιουργήσουμε έναν περιορισμό ξένου κλειδιού στο DepartmentId στον πίνακα Students, κάθε εισαγόμενο departmentId πρέπει να υπάρχει στον πίνακα Departments.

CREATE TABLE [Departments] (
	[DepartmentId] INTEGER  NOT NULL PRIMARY KEY AUTOINCREMENT,
	[DepartmentName] NVARCHAR(50)  NULL
);
CREATE TABLE [Students] (
	[StudentId] INTEGER  PRIMARY KEY AUTOINCREMENT NOT NULL,
	[StudentName] NVARCHAR(50)  NULL,
	[DepartmentId] INTEGER  NOT NULL,
	[DateOfBirth] DATE  NULL,
	FOREIGN KEY(DepartmentId) REFERENCES Departments(DepartmentId)
);

Για να ελέγξουμε πώς οι περιορισμοί ξένου κλειδιού μπορούν να αποτρέψουν την εισαγωγή ενός απροσδιόριστου στοιχείου ή τιμής σε έναν πίνακα που έχει σχέση με έναν άλλο πίνακα, θα εξετάσουμε το ακόλουθο παράδειγμα.

Σε αυτό το παράδειγμα, ο πίνακας Τμήματα έχει μια σχέση ξένου κλειδιού με τον πίνακα Φοιτητές, επομένως οποιαδήποτε τιμή departmentId που εισάγεται στον πίνακα Φοιτητές πρέπει να υπάρχει στον πίνακα Τμήματα. Εάν προσπαθήσετε να εισαγάγετε μια τιμή departmentId που δεν υπάρχει στον πίνακα Τμήματα, ο περιορισμός ξένου κλειδιού θα σας εμποδίσει να το κάνετε αυτό.

Ας εισαγάγουμε δύο τμήματα, το «Πληροφορική» και το «Τέχνες», στον πίνακα Τμημάτων με τα ακόλουθα Ερωτήματα INSERT:

INSERT INTO Departments VALUES(1, 'IT');
INSERT INTO Departments VALUES(2, 'Arts');

Οι δύο δηλώσεις θα πρέπει να εισάγουν δύο τμήματα στον πίνακα Τμήματα. Μπορείτε να επιβεβαιώσετε ότι οι δύο τιμές εισήχθησαν εκτελώντας στη συνέχεια το ερώτημα "SELECT * FROM Τμήματα":

Αποτέλεσμα ερωτήματος SELECT που εμφανίζει τα τμήματα Πληροφορικής και Τεχνών στο SQLite

Στη συνέχεια, προσπαθήστε να εισαγάγετε έναν νέο φοιτητή με αναγνωριστικό τμήματος που δεν υπάρχει στον πίνακα Τμήματα:

INSERT INTO Students(StudentName,DepartmentId) VALUES('John', 5);

Η γραμμή δεν θα εισαχθεί και θα εμφανιστεί ένα σφάλμα που θα αναφέρει: Ο περιορισμός ΕΞΩΤΕΡΙΚΟΥ ΚΛΕΙΔΙΟΥ απέτυχε.

SQLite Μήνυμα σφάλματος αποτυχίας περιορισμού ΕΞΩΤΕΡΙΚΟΥ ΚΛΕΙΔΙΟΥ

Διαφορά μεταξύ πρωτεύοντος κλειδιού και ξένου κλειδιού στο SQLite

Τα πρωτεύοντα και τα ξένα κλειδιά συμβάλλουν και τα δύο στη διατήρηση της ακεραιότητας των δεδομένων, αλλά παίζουν διαφορετικούς ρόλους. Ένα πρωτεύον κλειδί προσδιορίζει γραμμές μέσα σε έναν μόνο πίνακα, ενώ ένα ξένο κλειδί συνδέει γραμμές μεταξύ δύο σχετικών πινάκων. Ο παρακάτω πίνακας συνοψίζει τις κύριες διαφορές.

Βάση Πρωτεύων κλειδί Ξένο κλειδί
Σκοπός Προσδιορίζει μοναδικά κάθε γραμμή στον δικό της πίνακα Αναφέρεται στο πρωτεύον κλειδί ενός άλλου πίνακα για να τα συνδέσει
Μοναδικότητα Οι τιμές πρέπει να είναι μοναδικές Οι τιμές ενδέχεται να επαναλαμβάνονται, επομένως πολλές θυγατρικές σειρές μπορούν να μοιράζονται μία γονική γραμμή
Μηδενικές τιμές Δεν μπορεί να είναι null Μπορεί να είναι null όταν η σχέση είναι προαιρετική
Αριθμός ανά τραπέζι Μόνο ένα πρωτεύον κλειδί ανά πίνακα Ένας πίνακας μπορεί να έχει πολλά ξένα κλειδιά
Ευρετηρίαση Αυτόματη καταχώρηση Δεν καταχωρείται αυτόματα. Προσθέστε ένα για απόδοση

Στο παράδειγμα Φοιτητές και Τμήματα, το DepartmentId είναι το πρωτεύον κλειδί του πίνακα Departments και ένα ξένο κλειδί στον πίνακα Students, το οποίο συνδέει κάθε φοιτητή με ένα έγκυρο τμήμα.

SQLite Σύνθετο Πρωτεύον Κλειδί

Ένα σύνθετο πρωτεύον κλειδί είναι ένα πρωτεύον κλειδί που αποτελείται από δύο ή περισσότερες στήλες. Χρησιμοποιείται όταν καμία μεμονωμένη στήλη δεν είναι μοναδική από μόνη της, αλλά ο συνδυασμός στηλών είναι μοναδικός για κάθε γραμμή. SQLite αντιμετωπίζει τις συνδυασμένες τιμές ως ένα κλειδί.

Για παράδειγμα, ένας πίνακας εγγραφών μπορεί να επιτρέπει στον ίδιο φοιτητή πολλά μαθήματα και το ίδιο μάθημα για πολλούς φοιτητές, ωστόσο κάθε ζεύγος φοιτητή-μαθήματος θα πρέπει να εμφανίζεται μόνο μία φορά:

CREATE TABLE Enrollments (
	StudentId INTEGER NOT NULL,
	CourseId INTEGER NOT NULL,
	Grade TEXT,
	PRIMARY KEY (StudentId, CourseId)
);

Εδώ ούτε το StudentId ούτε το CourseId είναι μοναδικά από μόνα τους, αλλά το ζεύγος (StudentId, CourseId) είναι μοναδικό, επομένως ο ίδιος φοιτητής δεν μπορεί να εγγραφεί στο ίδιο μάθημα δύο φορές. Σημειώστε τα ακόλουθα σημεία όταν χρησιμοποιείτε ένα σύνθετο κλειδί:

  • Χρησιμοποιήστε ένα σύνθετο κλειδί όταν μια μεμονωμένη στήλη δεν μπορεί να προσδιορίσει με μοναδικό τρόπο μια γραμμή.
  • Κάθε στήλη στο σύνθετο κλειδί ακολουθεί τους κανόνες του πρωτεύοντος κλειδιού, επομένως η συνδυασμένη τιμή πρέπει να είναι μοναδική και όχι null.
  • Ένα σύνθετο κλειδί γράφεται ως ξεχωριστός όρος ΠΡΩΤΕΥΟΝΤΟΣ ΚΛΕΙΔΙ σε επίπεδο πίνακα, όχι μέσα σε έναν ορισμό μίας μόνο στήλης.

SQLite Ξένες βασικές ενέργειες: ΚΑΤΑ ΤΗ ΔΙΑΓΡΑΦΗ και ΚΑΤΑ ΤΗΝ ΕΝΗΜΕΡΩΣΗ

Ένα ξένο κλειδί μπορεί επίσης να ελέγξει τι συμβαίνει στις θυγατρικές γραμμές όταν η γονική γραμμή στην οποία αναφέρεται διαγράφεται ή ενημερώνεται. Αυτές οι ενέργειες αναφοράς προστίθενται με τους όρους ON DELETE και ON UPDATE όταν ορίζετε το ξένο κλειδί. SQLite υποστηρίζει πέντε δράσεις:

  • ΚΑΜΙΑ ΔΡΑΣΗ — η προεπιλεγμένη ενέργεια, η οποία εμφανίζει σφάλμα εάν οι θυγατρικές γραμμές εξακολουθούν να αναφέρονται στη γονική γραμμή.
  • ΠΕΡΙΟΡΙΖΩ — αποτρέπει την άμεση διαγραφή ή ενημέρωση, πριν από την εκτέλεση οποιασδήποτε άλλης αλλαγής.
  • SET NULL — ορίζει τη στήλη του θυγατρικού ξένου κλειδιού σε null.
  • ΡΥΘΜΙΣΤΕ ΤΟ DEFAULT — ορίζει τη στήλη του θυγατρικού ξένου κλειδιού στην δηλωμένη προεπιλεγμένη τιμή της.
  • CASCADE — εφαρμόζεται η ίδια αλλαγή στις θυγατρικές σειρές, επομένως η διαγραφή ενός γονικού στοιχείου διαγράφει και τις θυγατρικές του σειρές.

Το παρακάτω παράδειγμα αναδημιουργεί τον πίνακα Φοιτητές έτσι ώστε η διαγραφή ενός τμήματος να διαγράφει αυτόματα τους φοιτητές του και η ενημέρωση ενός αναγνωριστικού τμήματος ενημερώνει τους φοιτητές που ταιριάζουν:

CREATE TABLE Students (
	StudentId INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
	StudentName NVARCHAR(50) NULL,
	DepartmentId INTEGER NOT NULL,
	FOREIGN KEY(DepartmentId) REFERENCES Departments(DepartmentId)
		ON DELETE CASCADE
		ON UPDATE CASCADE
);

Να θυμάστε ότι οι ενέργειες αναφοράς εκτελούνται μόνο όταν είναι ενεργοποιημένη η υποστήριξη ξένων κλειδιών, επομένως εκτελέστε την PRAGMA foreign_keys = ON στην αρχή κάθε σύνδεσης. Χωρίς αυτήν, SQLite αναλύει τις ρήτρες ON DELETE και ON UPDATE, αλλά δεν τις επιβάλλει.

Συχνές Ερωτήσεις

Ναι. Όταν μια μεμονωμένη στήλη δηλώνεται ακριβώς ως ΑΚΕΡΑΙΟ ΠΡΩΤΕΥΟΝ ΚΛΕΙΔΙ, γίνεται ψευδώνυμο για το ενσωματωμένο rowid του πίνακα. SQLite Δεν διατηρεί ξεχωριστό ευρετήριο για αυτό, επομένως οι αναζητήσεις με αυτό το κλειδί είναι γρήγορες και δεν χρησιμοποιούν επιπλέον χώρο αποθήκευσης.

Η επιβολή ξένου κλειδιού παραμένει απενεργοποιημένη από προεπιλογή για να διατηρηθεί η συμβατότητα με παλαιότερες βάσεις δεδομένων και σενάρια που έχουν γραφτεί πριν από την έκδοση 3.6.19. Κάθε σύνδεση βάσης δεδομένων πρέπει να εκτελεί την PRAGMA foreign_keys = ON πριν από την SQLite ξεκινά τον έλεγχο των περιορισμών του ξένου κλειδιού.

SQLite ευρετηριάζει αυτόματα τα πρωτεύοντα κλειδιά και τις ΜΟΝΑΔΙΚΕΣ στήλες, αλλά δεν ευρετηριάζει τις στήλες ξένου κλειδιού. Επειδή η θυγατρική στήλη διαβάζεται σε κάθε έλεγχο περιορισμού, συνιστάται η δημιουργία του δικού σας ευρετηρίου σε κάθε στήλη ξένου κλειδιού για λόγους απόδοσης.

Αρ. ΑΛΛΑΓΗ ΠΙΝΑΚΑ σε SQLite Δεν είναι δυνατή η προσθήκη πρωτεύοντος ή ξένου κλειδιού σε έναν υπάρχοντα πίνακα. Μετονομάζετε τον παλιό πίνακα, δημιουργείτε έναν νέο πίνακα με το καθορισμένο κλειδί, αντιγράφετε τις γραμμές κατά μήκος με την εντολή INSERT SELECT και, στη συνέχεια, αποσύρετε τον παλιό πίνακα.

Ένα απλό ΑΚΕΡΑΙΟ ΠΡΩΤΕΥΟΝ ΚΛΕΙΔΙ αντιστοιχίζει το επόμενο αναγνωριστικό ως ένα πάνω από το μεγαλύτερο υπάρχον αναγνωριστικό γραμμής και μπορεί να επαναχρησιμοποιήσει αναγνωριστικά μετά από διαγραφές. ΑΥΤΟΜΑΤΗ ΠΡΟΣΑΥΞΗΣΗ tracks είναι το υψηλότερο αναγνωριστικό που χρησιμοποιήθηκε ποτέ στο sqlite_sequence και δεν επαναχρησιμοποιεί ποτέ μια τιμή, με μικρό κόστος απόδοσης.

Αυτό το σφάλμα εμφανίζεται όταν εισάγετε ή ενημερώνετε μια θυγατρική γραμμή της οποίας η τιμή ξένου κλειδιού δεν έχει αντίστοιχη γραμμή στον γονικό πίνακα ή όταν διαγράφετε μια γονική γραμμή που εξακολουθεί να έχει θυγατρικές γραμμές. Εισαγάγετε πρώτα τη γονική εγγραφή.

Ναι. Οι βοηθοί μετατροπής κειμένου σε SQL με τεχνητή νοημοσύνη μετατρέπουν μια απλή αγγλική περιγραφή των πινάκων σας σε προτάσεις CREATE TABLE με όρους PRIMARY KEY και FOREIGN KEY. Η παροχή του υπάρχοντος σχήματος βελτιώνει την ακρίβεια και η δημιουργημένη SQL θα πρέπει πάντα να ελέγχεται πριν από την εκτέλεση σε πραγματικά δεδομένα.

Ναί. GitHub Copilot προτείνει τη ΔΗΜΙΟΥΡΓΙΑ ΠΙΝΑΚΑ κώδικα με ΠΡΩΤΕΥΟΝ ΚΛΕΙΔΙ, ΞΕΝΟ ΚΛΕΙΔΙ και άλλους περιορισμούς ενσωματωμένους σε επεξεργαστές όπως VS CodeΔιαβάζει το υπάρχον σχήμα και τις μετεγκαταστάσεις σας, επομένως οι συμπληρώσεις του επαναχρησιμοποιούν τα πραγματικά ονόματα πινάκων και στηλών σας.

Συνοψίστε αυτήν την ανάρτηση με: