Можно ли сделать первичный ключ составным из нескольких полей
Что проверяют
Понимаете ли вы, что первичный ключ это ограничение, а не обязательно одна колонка id, и умеете ли придумать проверки на такое ограничение. Для тестировщика вопрос прикладной: от него зависят негативные кейсы и тесты на состояние гонки.
Как отвечать
Да, PRIMARY KEY (student_id, course_id) полностью валиден. Уникальной обязана быть комбинация целиком: пара повторяться не может, а каждая колонка по отдельности сколько угодно. Все части ключа при этом автоматически получают NOT NULL, и СУБД строит по ним уникальный индекс.
Уместный случай классический: таблица связи многие-ко-многим, у строки которой нет своего смысла вне пары. Альтернативу тоже стоит назвать: суррогатный id плюс ограничение UNIQUE на ту же пару. Гарантия та же, а внешним ключам и ORM с одной колонкой удобнее.
Что проверять тестами:
- вставка дубля пары падает с нарушением ограничения, а не проходит молча;
- строка, отличающаяся одной колонкой, вставляется;
NULLв любой части ключа отвергается;- две параллельные вставки одинаковой пары дают ошибку, а не две строки;
- ссылающаяся таблица объявляет внешний ключ сразу по обеим колонкам.
Где спотыкаются
Первое: тащат в ключ бизнес-данные. Пара «пользователь и дата заказа» уникальностью не обладает, два заказа в одну секунду ломают таблицу, а смена бизнес-правила потребует переделать и ключ, и все ссылки на него.
Второе: думают, что порядок колонок в ключе не важен. Индекс по паре помогает поиску по первой колонке и по обеим сразу, а по одной только второй он не работает: под такой запрос нужен отдельный индекс.
Третье: проверяют уникальность через интерфейс. Форма может не пускать дубль, а прямой запрос к API или одновременные запросы пройдут. Ограничение обязано стоять в базе, и проверять надо именно её реакцию, а не поведение экрана.