Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Primary Key
Primary Key (первичный ключ) — это столбец или группа столбцов в таблице базы данных, который уникально идентифицирует каждую строку. Это фундаментальное понятие в реляционных базах данных для обеспечения целостности данных и оптимизации поиска.
Характеристики Primary Key
- Уникальность — каждое значение должно быть уникальным в таблице
- Не может быть NULL — обязательно должно быть значение
- Идентификация — однозначно идентифицирует строку
- Индексирован — БД автоматически создает индекс для быстрого поиска
- Одна на таблицу — максимум один primary key (но может быть составной)
Примеры Primary Key
SQL синтаксис:
-- Простой Primary Key
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(100)
);
-- С AUTO_INCREMENT
CREATE TABLE posts (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(200),
content TEXT,
user_id INT
);
-- Составной Primary Key (несколько столбцов)
CREATE TABLE order_items (
order_id INT,
item_id INT,
quantity INT,
PRIMARY KEY (order_id, item_id)
);
Primary Key vs Unique Key
| Характеристика | Primary Key | Unique Key |
|---|---|---|
| Уникальность | Да | Да |
| NULL значения | Запрещены | Разрешены (множество) |
| Индексирование | Автоматическое | Да |
| Количество на таблицу | Максимум 1 | Не ограничено |
| Использование | Идентификация | Ограничение дубликатов |
CREATE TABLE users (
id INT PRIMARY KEY, -- Уникальный идентификатор
email VARCHAR(100) UNIQUE, -- Уникальный, но может быть NULL
phone VARCHAR(20) UNIQUE,
name VARCHAR(100)
);
Типы Primary Key
1. Natural Primary Key — использует существующий естественно уникальный атрибут:
CREATE TABLE countries (
iso_code CHAR(2) PRIMARY KEY, -- Код страны уникален
name VARCHAR(100),
population INT
);
2. Surrogate Primary Key — искусственно сгенерированный ключ:
CREATE TABLE products (
product_id INT AUTO_INCREMENT PRIMARY KEY, -- Искусственный ID
sku VARCHAR(100) UNIQUE,
name VARCHAR(100)
);
3. UUID Primary Key — глобально уникальный идентификатор:
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email VARCHAR(100) UNIQUE,
name VARCHAR(100)
);
Primary Key в Python/SQLAlchemy
from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.orm import declarative_base
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
# Простой primary key
id = Column(Integer, primary_key=True)
email = Column(String(100), unique=True, nullable=False)
name = Column(String(100))
# Создание таблицы
engine = create_engine('sqlite:///test.db')
Base.metadata.create_all(engine)
Составной Primary Key:
from sqlalchemy import Column, Integer, String, ForeignKey, PrimaryKeyConstraint
class OrderItem(Base):
__tablename__ = 'order_items'
order_id = Column(Integer, ForeignKey('orders.id'), primary_key=True)
item_id = Column(Integer, ForeignKey('items.id'), primary_key=True)
quantity = Column(Integer, default=1)
# Альтернативный синтаксис:
# __table_args__ = (PrimaryKeyConstraint('order_id', 'item_id'),)
UUID Primary Key:
import uuid
from sqlalchemy import Column, UUID
class User(Base):
__tablename__ = 'users'
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
email = Column(String(100), unique=True)
name = Column(String(100))
Foreign Key зависит от Primary Key
Primary Key и Foreign Key связаны:
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100)
);
CREATE TABLE posts (
id INT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(200),
user_id INT,
FOREIGN KEY (user_id) REFERENCES users(id)
);
В SQLAlchemy:
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(100))
posts = relationship('Post', back_populates='author')
class Post(Base):
__tablename__ = 'posts'
id = Column(Integer, primary_key=True)
title = Column(String(200))
user_id = Column(Integer, ForeignKey('users.id'))
author = relationship('User', back_populates='posts')
Ограничения и best practices
1. Выбор Primary Key:
-- ПЛОХО: Слишком большой
CREATE TABLE users (
email VARCHAR(255) PRIMARY KEY -- email может измениться
);
-- ХОРОШО: Маленький, неизменяемый
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(100) UNIQUE
);
2. Не используйте составные ключи без необходимости:
-- ПЛОХО: Слишком сложно для Foreign Keys
CREATE TABLE order_items (
order_date DATE,
order_sequence INT,
item_id INT,
quantity INT,
PRIMARY KEY (order_date, order_sequence, item_id)
);
-- ХОРОШО: Простой ID + уникальное ограничение
CREATE TABLE order_items (
id INT AUTO_INCREMENT PRIMARY KEY,
order_id INT,
item_id INT,
quantity INT,
UNIQUE(order_id, item_id)
);
3. Primary Key никогда не меняется:
# Плохо:
user.id = 999 # Никогда не меняйте primary key!
# Хорошо: если нужно изменить уникальное значение
user.email = 'newemail@example.com' # Это OK если есть UNIQUE constraint
Производительность Primary Key
Индекс на Primary Key:
-- Primary Key автоматически индексирован
-- Поиск по ID очень быстрый (B-tree индекс)
SELECT * FROM users WHERE id = 123; -- O(log n)
-- Vs без индекса
SELECT * FROM users WHERE email = 'test@example.com'; -- O(n) если нет индекса
SELECT * FROM users WHERE email = 'test@example.com' AND email IS UNIQUE; -- O(log n)
Когда нельзя использовать NULL в Primary Key
-- ОШИБКА: NULL в primary key запрещен
CREATE TABLE users (
id INT PRIMARY KEY,
email VARCHAR(100) -- Если это NULL, нарушается уникальность
);
INSERT INTO users VALUES (NULL, 'test@example.com'); -- Ошибка!
Итого
Primary Key это:
- Уникальный идентификатор каждой строки
- Основа для Foreign Keys и связей между таблицами
- Автоматически индексируется для быстрого поиска
- Обязателен в нормальной базе данных (3NF)
- Никогда не меняется — выбирайте тщательно
Обычно лучший выбор — это маленький числовой AUTO_INCREMENT ID или UUID, а не естественные атрибуты которые могут меняться.