I found a case where having no primary key makes sense. Think about watch time on video streaming platforms like YouTube, Netflix, etc. If you like to track the watch time of a user watching a specific video, I would create the following table:
CREATE TABLE `video_view` (
`user_id` INT NOT NULL,
`video_id` INT NOT NULL,
`datetime` DATETIME NOT NULL,
`video_time` FLOAT NOT NULL,
CONSTRAINT fk_user_id,
FOREIGN KEY (`user_id`) REFERENCES user(`id`)
ON DELETE CASCADE,
CONSTRAINT fk_video_ud,
FOREIGN KEY (`video_id`) REFERENCES video(`id`)
ON DELETE CASCADE
);
Now think of the situation a user is watching the same video at the same time in two windows or on two different machines. It is very unlikely that he will watch the same part of the video at the exact same time on two different devices. But it is possible. Therefore I chose not to create a primary key of user_id + video_id + date time (+ video_time).
There would be more possible solutions:
- Add an artificial primary key (I don't want that, it gives me no advantage in this case)
- Prevent from saving a data set with the same parameters (I don't want that, because that way I could not track that a user is watching the same video at the same time on two different devices)
- Add an identifier for a source (tab / device / etc.)
- Add another attribute count, which could be increased in case the very unlikely case happens
Other answers have already mentioned that in case of a logging table it could make sense not to have a primary key. I would define my table as a logging table, but it will be used for example for a view count on a video.