Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Реляционные базы данных
Реляционные БД — это системы хранения данных, организованные в виде таблиц (отношений) с рядами и столбцами. Это наиболее распространённый тип БД, используемый в большинстве приложений. Примеры: PostgreSQL, MySQL, SQLite, Oracle, SQL Server.
Основная концепция
Данные хранятся в таблицах, связанных между собой отношениями (relations):
-- Таблица пользователей
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(100) UNIQUE,
age INT
);
-- Таблица постов
CREATE TABLE posts (
id SERIAL PRIMARY KEY,
user_id INT REFERENCES users(id),
title VARCHAR(200),
content TEXT,
created_at TIMESTAMP
);
Визуально:
users table: posts table:
id | name | email | id | user_id | title | content
1 | Alice | a@e.c | 1 | 1 | Post1 | ...
2 | Bob | b@e.c | 2 | 1 | Post2 | ...
3 | Carol | c@e.c | 3 | 2 | Post3 | ...
Зачем нужны реляционные БД
1. Структурированное хранение данных:
# Вместо файла с хаотичными данными
import json
users = [
{"id": 1, "name": "Alice", "email": "a@e.c"},
{"id": 2, "name": "Bob", "email": "b@e.c"}
]
# Используем упорядоченную структуру в БД
import sqlite3
conn = sqlite3.connect('app.db')
cursor = conn.cursor()
# Данные организованы в таблицы с чётким схемой
cursor.execute('''
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
email TEXT UNIQUE
)
''')
2. Целостность данных:
-- Первичный ключ — гарантирует уникальность
CREATE TABLE users (
id INTEGER PRIMARY KEY, -- Уникален, не может быть NULL
name TEXT NOT NULL
);
-- Внешний ключ — гарантирует связь между таблицами
CREATE TABLE posts (
id INTEGER PRIMARY KEY,
user_id INTEGER NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(id)
-- Нельзя добавить post с несуществующим user_id
);
-- Уникальность
CREATE TABLE users (
id INTEGER PRIMARY KEY,
email TEXT UNIQUE -- Каждый email уникален
);
-- Проверка значений
CREATE TABLE users (
id INTEGER PRIMARY KEY,
age INTEGER CHECK (age >= 0 AND age <= 150)
);
3. Эффективное выполнение запросов:
-- SQL позволяет быстро искать, фильтровать и группировать данные
-- Найти всех пользователей старше 30 лет
SELECT * FROM users WHERE age > 30;
-- Найти посты конкретного пользователя
SELECT posts.* FROM posts
JOIN users ON posts.user_id = users.id
WHERE users.name = 'Alice';
-- Посчитать количество постов для каждого пользователя
SELECT users.name, COUNT(posts.id) as post_count
FROM users
LEFT JOIN posts ON users.id = posts.user_id
GROUP BY users.id;
Это намного быстрее, чем загружать всё в память и обрабатывать в Python:
# Плохо — загружаем всё в память
users = load_all_users_from_file()
filtered = [u for u in users if u['age'] > 30]
# Хорошо — БД делает фильтрацию сама
cursor.execute('SELECT * FROM users WHERE age > 30')
filtered = cursor.fetchall()
4. ACID свойства:
- Atomicity (Атомарность) — транзакция либо полностью выполнится, либо откатится
- Consistency (Согласованность) — данные всегда в согласованном состоянии
- Isolation (Изолированность) — параллельные транзакции не конфликтуют
- Durability (Долговечность) — данные сохраняются даже при сбое
import sqlite3
conn = sqlite3.connect('app.db')
cursor = conn.cursor()
try:
# Начало транзакции
cursor.execute('BEGIN TRANSACTION')
# Перевод денег
cursor.execute('UPDATE accounts SET balance = balance - 100 WHERE id = 1')
cursor.execute('UPDATE accounts SET balance = balance + 100 WHERE id = 2')
# Если что-то пошло не так, все изменения откатываются
conn.commit() # Фиксируем изменения
except Exception as e:
conn.rollback() # Откатываем, если ошибка
raise
5. Масштабируемость и многопользовательский доступ:
-- Несколько приложений могут работать с одной БД одновременно
-- БД управляет блокировками и конфликтами
-- Приложение 1: обновляет профиль
UPDATE users SET name = 'Alice Smith' WHERE id = 1;
-- Приложение 2: читает профиль (видит обновленные данные)
SELECT * FROM users WHERE id = 1;
Структура реляционной БД
Первичный ключ (Primary Key):
CREATE TABLE users (
id INTEGER PRIMARY KEY, -- Уникальный идентификатор
name TEXT
);
Внешний ключ (Foreign Key):
CREATE TABLE posts (
id INTEGER PRIMARY KEY,
user_id INTEGER,
FOREIGN KEY (user_id) REFERENCES users(id) -- Связь с таблицей users
);
Индексы (Indexes):
-- Ускоряет поиск по email
CREATE INDEX idx_email ON users(email);
-- Теперь запрос выполнится быстрее
SELECT * FROM users WHERE email = 'alice@example.com';
Пример с Python (SQLAlchemy ORM)
from sqlalchemy import create_engine, Column, Integer, String, DateTime, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, relationship
from datetime import datetime
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(100))
email = Column(String(100), unique=True)
posts = relationship('Post', back_populates='author')
class Post(Base):
__tablename__ = 'posts'
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey('users.id'))
title = Column(String(200))
content = Column(String)
created_at = Column(DateTime, default=datetime.utcnow)
author = relationship('User', back_populates='posts')
# Создание БД
engine = create_engine('sqlite:///app.db')
Base.metadata.create_all(engine)
# Работа с данными
Session = sessionmaker(bind=engine)
session = Session()
# Создание пользователя
user = User(name='Alice', email='alice@example.com')
session.add(user)
session.commit()
# Создание поста
post = Post(title='First Post', content='Hello!', author=user)
session.add(post)
session.commit()
# Запрос
user = session.query(User).filter_by(name='Alice').first()
print(user.posts) # [<Post title='First Post'>]
Реляционные БД vs NoSQL
Реляционные БД:
- Структурированные данные
- Сложные связи
- Нужна целостность
- SQL запросы
- Пример: PostgreSQL, MySQL
NoSQL (MongoDB, Redis):
- Неструктурированные данные
- Гибкая схема
- Горизонтальная масштабируемость
- JSON/документы
# Реляционная БД
users = [{'id': 1, 'name': 'Alice'}, ...]
posts = [{'id': 1, 'user_id': 1, 'title': '...'}, ...]
# NoSQL (MongoDB)
# Данные могут быть вложенными
user = {
'id': 1,
'name': 'Alice',
'posts': [
{'id': 1, 'title': 'Post 1'},
{'id': 2, 'title': 'Post 2'}
]
}
Выводы
Реляционные БД нужны для:
- Надёжного хранения структурированных данных
- Обеспечения целостности через ограничения и связи
- Эффективных запросов через индексы и оптимизацию
- Многопользовательского доступа с транзакциями
- Долговечности данных при сбоях
Реляционные БД — это стандарт для большинства бизнес-приложений. Они мощные, проверенные и обеспечивают надёжность, которая критична для бизнеса.