SQL: Βασικές Εντολές και Διαχείριση Βάσεων Δεδομένων
Το SQL (Structured Query Language) είναι η γλώσσα που χρησιμοποιείται για τη δημιουργία, την ανάγνωση, την ενημέρωση και τη διαχείριση δεδομένων σε σχεσιακές βάσεις δεδομένων. Το παρακάτω Cheat Sheet χρησιμοποιεί κυρίως σύνταξη συμβατή με MySQL. Ορισμένες λειτουργίες διαφέρουν ανάμεσα σε MySQL, PostgreSQL, SQL Server και SQLite.
Βασικές έννοιες
- Database: οργανωμένη συλλογή δεδομένων.
- Table: δεδομένα σε γραμμές (rows) και στήλες (columns).
- Primary Key: μοναδικό αναγνωριστικό κάθε εγγραφής.
- Foreign Key: σύνδεση εγγραφών μεταξύ πινάκων.
- NULL: απουσία τιμής, δεν είναι ίδιο με το 0 ή το κενό string.
Δημιουργία και επιλογή βάσης δεδομένων
CREATE DATABASE grcodeclub;
SHOW DATABASES;
USE grcodeclub;
-- Διαγραφή βάσης (προσοχή: διαγράφει όλα τα δεδομένα)
DROP DATABASE IF EXISTS old_database;
Δημιουργία και διαχείριση πινάκων
Ορίζουμε τύπους δεδομένων, περιορισμούς και κλειδιά κατά τη δημιουργία ενός πίνακα.
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(150) NOT NULL UNIQUE,
age TINYINT UNSIGNED,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Εμφάνιση δομής
DESCRIBE users;
-- Προσθήκη στήλης
ALTER TABLE users ADD COLUMN is_active BOOLEAN DEFAULT TRUE;
-- Τροποποίηση / διαγραφή στήλης
ALTER TABLE users MODIFY username VARCHAR(80) NOT NULL;
ALTER TABLE users DROP COLUMN age;
-- Διαγραφή πίνακα
DROP TABLE IF EXISTS users;
Συνηθισμένοι τύποι δεδομένων
| Τύπος | Χρήση |
|---|---|
| INT / BIGINT | Ακέραιοι αριθμοί |
| DECIMAL(10,2) | Ακριβείς δεκαδικές τιμές, π.χ. χρηματικά ποσά |
| VARCHAR(n) | Κείμενο μεταβλητού μήκους |
| TEXT | Μεγαλύτερα κείμενα |
| DATE | Ημερομηνία |
| DATETIME / TIMESTAMP | Ημερομηνία και ώρα |
| BOOLEAN | Λογική τιμή (η υλοποίηση διαφέρει ανά DBMS) |
Περιορισμοί (Constraints)
Οι περιορισμοί προστατεύουν την ακεραιότητα των δεδομένων.
CREATE TABLE products (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
sku VARCHAR(40) UNIQUE,
price DECIMAL(10,2) CHECK (price >= 0),
category_id INT,
FOREIGN KEY (category_id) REFERENCES categories(id)
);
| Constraint | Λειτουργία |
|---|---|
| PRIMARY KEY | Μοναδικό και μη κενό κλειδί |
| FOREIGN KEY | Αναφορά σε κλειδί άλλου πίνακα |
| NOT NULL | Απαγορεύει NULL τιμές |
| UNIQUE | Απαγορεύει διπλότυπες τιμές |
| DEFAULT | Ορίζει προεπιλεγμένη τιμή |
| CHECK | Ελέγχει μια συνθήκη |
Εισαγωγή δεδομένων – INSERT
INSERT INTO users (username, email)
VALUES ('dimitris', 'dimitris@example.com');
-- Πολλαπλές εγγραφές
INSERT INTO users (username, email) VALUES
('maria', 'maria@example.com'),
('nikos', 'nikos@example.com');
Ανάκτηση δεδομένων – SELECT
SELECT * FROM users;
SELECT username, email FROM users;
SELECT DISTINCT username FROM users;
-- Ψευδώνυμα στηλών και πινάκων
SELECT username AS name FROM users AS u;
Φιλτράρισμα – WHERE
Χρησιμοποιούμε συνθήκες για να περιορίσουμε τα αποτελέσματα.
SELECT * FROM users WHERE id = 1;
SELECT * FROM users WHERE age >= 18;
SELECT * FROM users WHERE username = 'maria';
SELECT * FROM users WHERE age BETWEEN 18 AND 30;
SELECT * FROM users WHERE username IN ('maria', 'nikos');
SELECT * FROM users WHERE email LIKE '%@example.com';
SELECT * FROM users WHERE age IS NULL;
-- Συνδυασμός συνθηκών
SELECT * FROM users WHERE age >= 18 AND is_active = TRUE;
SELECT * FROM users WHERE age < 18 OR age > 65;
Ταξινόμηση και περιορισμός αποτελεσμάτων
SELECT * FROM users ORDER BY username ASC;
SELECT * FROM users ORDER BY created_at DESC;
SELECT * FROM users LIMIT 10;
-- MySQL / PostgreSQL
SELECT * FROM users LIMIT 10 OFFSET 20;
Ενημέρωση και διαγραφή εγγραφών
Πάντα έλεγχε το WHERE πριν από UPDATE ή DELETE. Χωρίς αυτό μπορεί να επηρεαστούν όλες οι εγγραφές.
UPDATE users
SET email = 'new@example.com'
WHERE id = 1;
DELETE FROM users WHERE id = 1;
-- Διαγραφή όλων των εγγραφών, διατηρείται ο πίνακας
DELETE FROM users;
Συγκεντρωτικές συναρτήσεις – Aggregate Functions
SELECT COUNT(*) AS total_users FROM users;
SELECT MIN(price), MAX(price), AVG(price), SUM(price)
FROM products;
SELECT category_id, COUNT(*) AS total
FROM products
GROUP BY category_id
HAVING COUNT(*) > 5;
| Συνάρτηση | Περιγραφή |
|---|---|
| COUNT() | Μετρά εγγραφές ή μη NULL τιμές |
| SUM() | Άθροισμα |
| AVG() | Μέσος όρος |
| MIN() | Ελάχιστη τιμή |
| MAX() | Μέγιστη τιμή |
JOIN – Συνδυασμός πινάκων
Τα JOIN συνδέουν δεδομένα από δύο ή περισσότερους πίνακες μέσω σχετικών στηλών.
-- Μόνο εγγραφές με αντιστοιχία
SELECT users.username, orders.total
FROM users
INNER JOIN orders ON orders.user_id = users.id;
-- Όλοι οι χρήστες, ακόμη και χωρίς παραγγελίες
SELECT users.username, orders.total
FROM users
LEFT JOIN orders ON orders.user_id = users.id;
-- CROSS JOIN: καρτεσιανό γινόμενο
SELECT * FROM sizes CROSS JOIN colors;
| JOIN | Αποτέλεσμα |
|---|---|
| INNER JOIN | Μόνο οι εγγραφές που ταιριάζουν και στους δύο πίνακες |
| LEFT JOIN | Όλες οι εγγραφές του αριστερού πίνακα και οι αντίστοιχες του δεξιού |
| RIGHT JOIN | Όλες οι εγγραφές του δεξιού πίνακα και οι αντίστοιχες του αριστερού |
| CROSS JOIN | Όλοι οι δυνατοί συνδυασμοί εγγραφών |
Υποερωτήματα – Subqueries
SELECT username
FROM users
WHERE id IN (
SELECT user_id FROM orders WHERE total > 100
);
CASE – Συνθήκες σε αποτελέσματα
SELECT name, price,
CASE
WHEN price >= 100 THEN 'Ακριβό'
WHEN price >= 50 THEN 'Μεσαίο'
ELSE 'Οικονομικό'
END AS price_group
FROM products;
Views – Προβολές
Ένα VIEW αποθηκεύει ένα ερώτημα ως επαναχρησιμοποιήσιμη εικονική προβολή.
CREATE VIEW active_users AS
SELECT id, username, email
FROM users
WHERE is_active = TRUE;
SELECT * FROM active_users;
DROP VIEW active_users;
Indexes – Ευρετήρια
Τα indexes μπορούν να επιταχύνουν αναζητήσεις, αλλά αυξάνουν το κόστος αποθήκευσης και εγγραφών.
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_orders_user_date ON orders(user_id, created_at);
SHOW INDEX FROM users;
DROP INDEX idx_users_email ON users;
Transactions – Συναλλαγές
Οι συναλλαγές επιτρέπουν να εκτελούνται πολλές αλλαγές ως μία λογική μονάδα. Η υποστήριξη εξαρτάται από το storage engine και το DBMS.
START TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
-- Οριστικοποίηση
COMMIT;
-- Σε περίπτωση σφάλματος, αντί για COMMIT:
-- ROLLBACK;
CTE – Common Table Expressions
Τα CTE ορίζονται με WITH και κάνουν σύνθετα ερωτήματα πιο ευανάγνωστα.
WITH expensive_products AS (
SELECT id, name, price
FROM products
WHERE price > 100
)
SELECT * FROM expensive_products;
Window Functions
SELECT
username,
department_id,
salary,
ROW_NUMBER() OVER (
PARTITION BY department_id
ORDER BY salary DESC
) AS salary_rank
FROM employees;
Χρήσιμες συναρτήσεις
-- Κείμενο
SELECT UPPER(username), LOWER(email), LENGTH(username)
FROM users;
-- Αριθμητικές
SELECT ROUND(price, 2), ABS(-25);
-- Ημερομηνίες (σύνταξη ανά DBMS)
SELECT CURRENT_DATE, CURRENT_TIMESTAMP;
-- NULL handling
SELECT COALESCE(phone, 'Δεν έχει καταχωριστεί') FROM users;
Ασφάλεια SQL και Prepared Statements
Μην ενώνεις απευθείας τιμές χρηστών μέσα σε SQL strings. Χρησιμοποίησε παραμετροποιημένα queries / prepared statements από τη γλώσσα εφαρμογής.
-- Ενδεικτική μορφή παραμετροποιημένου query
SELECT id, username FROM users WHERE email = ?;
Σημαντικές πρακτικές
- Χρησιμοποίησε PRIMARY KEY σε κάθε πίνακα όπου απαιτείται μοναδική ταυτοποίηση.
- Δήλωνε ρητά τις στήλες στα INSERT αντί για INSERT χωρίς column list.
- Χρησιμοποίησε κατάλληλους τύπους δεδομένων και constraints.
- Πρόσθεσε indexes σε στήλες που χρησιμοποιούνται συχνά σε αναζητήσεις και JOIN, αφού εξετάσεις το execution plan.
- Πρόσεχε ιδιαίτερα UPDATE και DELETE χωρίς WHERE.
- Χρησιμοποίησε least-privilege λογαριασμούς βάσης και prepared statements.