Отличный вопрос. Мне нравится тот факт, что вы оцениваете возможные несоответствия. В этом случае я бы сказал, что первое решение является правильным, с одной небольшой модификацией: первичный ключ ProposedTime должен быть составным первичным ключом, который включает meetingId.
Для этого есть несколько причин: во-первых, предложенное время явно не может существовать без встречи, и, что более важно, оно не может существовать без конкретной встречи. По сути, предложенное время не может быть определено, кроме как в контексте собрания, и как таковое его определение не должно позволять ему оставаться в одиночестве.
Во-вторых, эта зависимость недостаточно выражена при использовании MeetingId в качестве обязательного атрибута. Например, не имеет смысла обновлять поле meetingId предлагаемого времени. «Давайте перенесем 9 утра на другую встречу!». Ввиду того, что meetingId является частью первичного ключа, явно препятствует такого рода бессмысленному обновлению, потому что обновленный первичный ключ - это, по сути, другая вещь.
Наконец, тот факт, что предлагаемое время имеет логически неполный ключ, является одной из первых вещей, с которыми вы столкнулись при попытке использовать его надлежащим образом. Каждое отношение к базе данных, в идеале, должно быть декларативно согласованным. То есть, если вы можете выразить отношение «у львов есть два родителя», один родитель не должен быть белкой. Очевидно, что производительность и ограничения платформы означают, что вы не всегда можете достичь этой цели, но такое несоответствие можно рассматривать как «запах кода», который может потребовать дальнейшего изучения. В вашем случае исправление кажется небольшим и производительным.
tl; dr: добавьте MeetingId к PK предлагаемого времени и перейдите к первому решению.