Может ли быть два одинаковых значения в столбце FOREIGN KEY в БД?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Может ли быть два одинаковых значения в столбце 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 ограничение.