Как правильно сделать непрочитанные уведомления на сайте?
Если новость и достижение относится только к одному пользователю, то есть смысл ввести ячейку с флагом в саму таблицу с новостями, или достижениями.
Если одна новость может относится ко многим пользователям, то отдельную таблицу в которую вводить связи между новостями и пользователями, тоесть был просмотр внесли запись. Далее проверять на наличие записи.
Как вариант, отдельная табличка с уведомлениями, и при создании новости, вносить в неё запись о уведомлении. Вариантов масса, нужно исходить из деталей по задаче
Сделайте поле в таблице с пользователями, например history или user_settings, туда пихайте массив преобразованный в json. id статей, которые читал пользователь, разделы с подпиской, цвет трусов на аватарке и так далее. При авторизации инфа с пользователем попадает в сессию всместе с  history (user_setting). Далее просто тянете все статьи, id которых нет в сессии. 
Минус - подрастет таблица user (если не увлекаться и не пихать туда все что не попади - будет вполне сносно), плюсы - нет доп запросов к БД и они максимально простые.