← Назад к вопросам

Для чего нужен первичный ключ (Primary Key)?

1.0 Junior🔥 301 комментариев
#Базы данных (SQL)

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Первичный ключ (Primary Key)

Первичный ключ — это одно или несколько полей в таблице, которые однозначно идентифицируют каждую строку. Это фундаментальное понятие в реляционных БД.

Основные функции Primary Key

  1. Уникальность — каждая строка имеет уникальное значение
  2. Идентификация — по PK можно быстро найти конкретную строку
  3. Связь между таблицами — Foreign Key ссылаются на Primary Key
  4. Целостность данных — предотвращает дубликаты

Синтаксис в SQL

-- Single column Primary Key
CREATE TABLE users (
    id INT PRIMARY KEY,
    email VARCHAR(100),
    name VARCHAR(100)
);

-- Или как constraint
CREATE TABLE users (
    id INT,
    email VARCHAR(100),
    PRIMARY KEY (id)
);

-- Composite Primary Key (несколько полей)
CREATE TABLE user_roles (
    user_id INT,
    role_id INT,
    assigned_date DATE,
    PRIMARY KEY (user_id, role_id)  -- Уникальная комбинация
);

В SQLAlchemy (Python ORM)

from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import declarative_base

Base = declarative_base()

class User(Base):
    __tablename__ = "users"
    
    # Single column PK
    id = Column(Integer, primary_key=True)
    email = Column(String(100), nullable=False)
    name = Column(String(100))


class UserRole(Base):
    __tablename__ = "user_roles"
    
    # Composite PK
    user_id = Column(Integer, primary_key=True)
    role_id = Column(Integer, primary_key=True)
    assigned_date = Column(Date)

Свойства Primary Key

  1. NOT NULL — значение обязательно
  2. UNIQUE — значение не повторяется
  3. Индексируется — автоматически создаётся индекс (быстрый поиск)
  4. Один на таблицу — только один Primary Key (но может быть Composite)

Типичные примеры

ID как Primary Key

CREATE TABLE products (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100),
    price DECIMAL(10, 2)
);

INSERT INTO products (name, price) VALUES ("Laptop", 999.99);
-- id автоматически будет 1

INSERT INTO products (name, price) VALUES ("Mouse", 29.99);
-- id будет 2

UUID как Primary Key

from uuid import uuid4
from sqlalchemy import Column, String

class User(Base):
    __tablename__ = "users"
    
    id = Column(
        String(36),
        primary_key=True,
        default=lambda: str(uuid4())
    )
    email = Column(String(100), unique=True)

Email как Primary Key (редко)

CREATE TABLE accounts (
    email VARCHAR(100) PRIMARY KEY,
    name VARCHAR(100),
    created_at TIMESTAMP
);

Foreign Key и связи

Foreign Key ссылаются на Primary Key другой таблицы:

CREATE TABLE users (
    id INT PRIMARY KEY,
    email VARCHAR(100)
);

CREATE TABLE posts (
    id INT PRIMARY KEY,
    title VARCHAR(200),
    user_id INT,
    FOREIGN KEY (user_id) REFERENCES users(id)
);

Теперь posts.user_id может ссылаться только на существующий users.id.

В Python с SQLAlchemy

from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship

class User(Base):
    __tablename__ = "users"
    
    id = Column(Integer, primary_key=True)
    email = 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")


# Использование
user = User(email="john@example.com")
post = Post(title="My first post", author=user)
session.add(user)
session.commit()
# БД автоматически установит post.user_id = user.id

Natural Key vs Surrogate Key

Natural Key — использует реальные данные (email, passport number):

CREATE TABLE employees (
    passport_id VARCHAR(20) PRIMARY KEY,
    name VARCHAR(100),
    position VARCHAR(100)
);

Проблемы:

  • Может измениться (passport переоформляют)
  • Может быть null
  • Может быть очень большой

Surrogate Key — синтетический ID (INT, UUID):

CREATE TABLE employees (
    id INT PRIMARY KEY AUTO_INCREMENT,
    passport_id VARCHAR(20),
    name VARCHAR(100),
    position VARCHAR(100),
    UNIQUE KEY (passport_id)  -- Но не Primary Key
);

Преимущества:

  • Никогда не меняется
  • Компактный
  • Стандартный подход

Производительность

Primary Key автоматически создаёт индекс, поэтому:

-- БЫСТРО (используется индекс)
SELECT * FROM users WHERE id = 123;

-- МЕДЛЕННО (полный скан таблицы)
SELECT * FROM users WHERE name = "John";

Лучшие практики

  1. Всегда используй Primary Key — каждая таблица должна его иметь
  2. Используй Surrogate Key — INT или UUID, не Natural Key
  3. Делай его small — маленький размер = быстрый поиск
  4. Auto-increment или UUID — выбирай в зависимости от распределённости
  5. Защищай связи — используй Foreign Key для целостности

Вывод: Primary Key — это основа реляционной БД, обеспечивает уникальность, быстрый поиск и связь между таблицами.

Для чего нужен первичный ключ (Primary Key)? | PrepBro