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

Может ли быть два одинаковых значения в столбце FOREIGN KEY в БД?

2.0 Middle🔥 101 комментариев
#Базы данных и SQL

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

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

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

Может ли быть два одинаковых значения в столбце FOREIGN KEY

Да, абсолютно да. Это нормально и частая ситуация в базах данных.

Основной принцип: Foreign Key != Unique

Foreign Key (FK) - это просто ограничение, которое требует, чтобы значение существовало в родительской таблице. Оно НЕ требует уникальности.

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

CREATE TABLE orders (
    id INT PRIMARY KEY,
    user_id INT REFERENCES users(id),
    amount DECIMAL
);

Примеры допустимых данных:

users таблица:
id | name
---|-------
1  | Alice
2  | Bob
3  | Charlie

orders таблица:
id | user_id | amount
---|---------|--------
1  | 1       | 100
2  | 1       | 200  (ДА! Два заказа от Alice)
3  | 2       | 150
4  | 1       | 300  (И третий заказ от Alice)
5  | 3       | 50

Повторяющиеся значения FK - это нормально и ожидаемо.

Реальные примеры

Пример 1: Многие-к-одному (Many-to-One)

Сотрудник -> Отдел

CREATE TABLE departments (
    id INT PRIMARY KEY,
    name VARCHAR(100)
);

CREATE TABLE employees (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    department_id INT REFERENCES departments(id)
);

В одном отделе много сотрудников - это совершенно нормально.

Пример 2: Комментарии на посте

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

CREATE TABLE comments (
    id INT PRIMARY KEY,
    post_id INT REFERENCES posts(id),
    user_id INT REFERENCES users(id),
    text TEXT
);

Много комментариев одного поста - это означает много одинаковых post_id.

Foreign Key vs Unique Key

Если ты хочешь, чтобы FK были УНИКАЛЬНЫЕ, нужно добавить UNIQUE ограничение:

-- Без UNIQUE - могут быть повторения
CREATE TABLE orders (
    id INT PRIMARY KEY,
    user_id INT REFERENCES users(id)
);

-- С UNIQUE - только одно значение на пользователя
CREATE TABLE preferences (
    id INT PRIMARY KEY,
    user_id INT UNIQUE REFERENCES users(id)
);

Пример в Java с Hibernate

@Entity
@Table(name = "users")
public class User {
    @Id
    private Long id;
    private String name;
    
    @OneToMany(mappedBy = "user")
    private List<Order> orders = new ArrayList<>();
}

@Entity
@Table(name = "orders")
public class Order {
    @Id
    private Long id;
    
    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;  // Foreign Key
    
    private BigDecimal amount;
}

// Допустимо:
User alice = userRepository.findById(1L);

Order order1 = new Order();
order1.setUser(alice);      // FK к Alice
order1.setAmount(100);

Order order2 = new Order();
order2.setUser(alice);      // FK к Alice (повтор, но OK)
order2.setAmount(200);

Что происходит при нарушении FK

-- Это ЗАПРЕТИТ БД
INSERT INTO orders VALUES (10, 999, 100);
-- ERROR: Foreign key constraint fails

-- Это РАЗРЕШИТ БД
INSERT INTO orders VALUES (10, 1, 100);
INSERT INTO orders VALUES (11, 1, 200);
INSERT INTO orders VALUES (12, 1, 300);
-- OK: user_id=1 существует (повторение не проблема)

Таблица: Constraints

ConstraintУникальностьМножественность
PRIMARY KEYУникаленТолько 1
UNIQUE KEYУникаленНесколько
FOREIGN KEYНЕ требуетМного значений

Частые ошибки

Ошибка 1: Путаница PRIMARY KEY vs FOREIGN KEY

PRIMARY KEY - уникален, только одно значение FOREIGN KEY - может быть много одинаковых

Ошибка 2: Ожидание, что FK будет уникален

Если ты пишешь:

Order order = orderRepository.findByUserId(1L);

Это может вернуть только ПЕРВЫЙ заказ user_id=1! Правильно:

List<Order> orders = orderRepository.findAllByUserId(1L);

Ошибка 3: FK может быть NULL

-- Если FK может быть NULL:
user_id INT REFERENCES users(id)

-- Если НЕ может быть NULL:
user_id INT NOT NULL REFERENCES users(id)

Заключение

ДА, могут быть два и более одинаковых значения в столбце FK. Это нормально и ожидаемо. Foreign Key проверяет только существование значения, не его уникальность. Если нужна уникальность, добавь UNIQUE ограничение.