Один важный факт, который вам необходимо учитывать (в зависимости от проблемной области), заключается в том, что люди меняют адреса и могут заранее сообщить вам об изменении своего адреса; это, безусловно, верно для коммунальных предприятий, операторов связи и т. д.
В этом случае вам необходимо иметь возможность хранить несколько адресов для клиента с датами действия, чтобы можно было заранее настроить адрес и автоматически переключаться в нужную точку. Если это требование, то вариант (2) является единственным разумным способом его моделирования, например,
Customer (id, ...)
Address (id, customer_id, address_type, valid_from, valid_to)
С другой стороны, если вам не нужно обслуживать это (и вы уверены, что в будущем это не так), то, вероятно, (1) проще управлять, поскольку гораздо проще поддерживать целостность данных, поскольку нет проблем с обеспечением того, что существует только один адрес того же типа, и объединения становятся проще, поскольку они находятся только в одном поле.
Так что (1) или (2) хорошо в зависимости от того, нужны ли вам домашние переезды, но я бы держался подальше от (3), потому что вы затем повторяете определение адреса в таблице, и вам придется добавить несколько столбцов, если вы измените, как выглядит адрес. Возможно, это немного более производительно, но, честно говоря, когда вы имеете дело с правильно проиндексированными объединениями в реляционной базе данных, получить не так уж и много, и, скорее всего, это будет медленнее в некоторых сценариях, когда вы этого не делаете нужен адрес, так как размер записи для клиента будет больше.