CREATE TABLE users (
user_id INTEGER PRIMARY KEY,
email VARCHAR(255) NOT NULL UNIQUE,
created_at TIMESTAMP NOT NULL
);Use explicit types and constraints to enforce data quality.
Create and change schema objects, then insert, update, delete, merge, and manage transactional data changes.
Build and change schema objects.
CREATE TABLE users (
user_id INTEGER PRIMARY KEY,
email VARCHAR(255) NOT NULL UNIQUE,
created_at TIMESTAMP NOT NULL
);Use explicit types and constraints to enforce data quality.
ALTER TABLE users
ADD COLUMN last_login_at TIMESTAMP;ALTER TABLE changes schema without recreating the table.
ALTER TABLE orders
ADD CONSTRAINT fk_orders_customer
FOREIGN KEY (customer_id) REFERENCES customers(customer_id);Constraints help maintain relational integrity.
DROP TABLE old_logs;Be careful: dropping a table deletes its data. Some engines support IF EXISTS.
TRUNCATE TABLE staging_events;TRUNCATE is often faster than DELETE for clearing a table.
Enforce integrity and speed up lookups.
CREATE TABLE departments (
department_id INTEGER PRIMARY KEY,
name VARCHAR(100) NOT NULL
);Primary keys uniquely identify each row.
ALTER TABLE users
ADD CONSTRAINT uq_users_email UNIQUE (email);Unique constraints prevent duplicate values.
ALTER TABLE products
ADD CONSTRAINT chk_price_positive CHECK (price >= 0);CHECK constraints enforce domain rules inside the database.
CREATE INDEX idx_orders_customer_id
ON orders (customer_id);Indexes speed up reads but add write overhead and storage cost.
CREATE INDEX idx_orders_customer_created
ON orders (customer_id, created_at);Column order matters in composite indexes.
Modify table data.
INSERT INTO users (user_id, email, created_at)
VALUES (1, 'a@example.com', CURRENT_TIMESTAMP);Specify column names explicitly for clarity and safety.
INSERT INTO roles (role_id, role_name)
VALUES
(1, 'admin'),
(2, 'editor'),
(3, 'viewer');Multi-row INSERT is concise and often more efficient than repeated single-row inserts.
INSERT INTO active_customers (customer_id, email)
SELECT customer_id, email
FROM customers
WHERE status = "active";Great for staging and snapshot tables.
UPDATE users
SET status = 'inactive'
WHERE last_login_at < DATE '2024-01-01';Always confirm the WHERE clause before running UPDATE in production.
DELETE FROM sessions
WHERE expires_at < CURRENT_TIMESTAMP;DELETE removes rows one by one from the table.
MERGE INTO inventory AS target
USING incoming_inventory AS src
ON target.sku = src.sku
WHEN MATCHED THEN UPDATE SET quantity = src.quantity
WHEN NOT MATCHED THEN INSERT (sku, quantity) VALUES (src.sku, src.quantity);MERGE support and exact syntax vary by dialect. Some engines use ON CONFLICT or ON DUPLICATE KEY UPDATE instead.
Control units of work and isolation boundaries.
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;
COMMIT;If something fails, use ROLLBACK instead of COMMIT.
BEGIN;
SAVEPOINT before_optional_step;
UPDATE orders SET status = "archived" WHERE order_id = 10;
ROLLBACK TO SAVEPOINT before_optional_step;
COMMIT;Savepoints let you recover from part of a transaction without aborting the whole unit of work.
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;Isolation level support can vary across engines, but this is a core transactional concept.