Оба решения, которые вы предлагаете, не имеют реальных внешних ключей. В первом решении один foreign_id может указывать на множество таблиц, что трудно (или, по крайней мере, неэффективно) для принудительного применения базы данных. Второе решение хранит несколько значений в одном столбце, и это то, что все соглашаются с тем, что вам не следует делать это (оно нарушает первую нормальную форму .)
Я бы сделал следующее: города, почтовые индексы и штаты имеют географическое положение. Обычный способ реализовать это - отношение один ко многим. Создайте таблицу геолокации и добавьте столбец geolocation_id к городам, почтовому индексу и таблицам состояний.
РЕДАКТИРОВАТЬ: Для вашего комментария, чтобы добраться от геолокации в свои города:
select *
from geolocation g
left join cities c
on g.id = c.geolocation_id
left join zipcodes z
on g.id = z.geolocation_id
....
База данных будет разрешать объединения с использованием индекса внешнего ключа, что очень быстро.