Я думаю, что это хорошо или нет, зависит от вашего дизайна.
Счет должен содержать данные такими, какими они были на момент создания или отправки счета. Таким образом, могут потребоваться данные, относящиеся к данным клиента, но не напрямую к внешнему ключу, особенно если вы используете естественный ключ.
Например, предположим, что Мэри Джонс заказала что-то и ей выставили счет 31 мая 2010 года. 12 сентября 2010 года она сменила имя на Мэри Джонс-Смит и переехала на адрес своего мужа. Счет, являющийся изображением во времени, должен содержать имя Мэри Джонс и оригинальный адрес, на который он был отправлен. Лучше всего сохранить ссылку на текущего клиента и его информацию (поэтому я должен иметь идентификатор клиента в таблице клиентов при изменении имен и таблицу счетов FK of Customerid). Но хранить Мэри Джонс, когда Мэри Джонс больше не существует в таблице клиентов, - это не только нормально, необходимо отслеживать, что на самом деле произошло.
То же самое с продуктами и ценами и счетами. Вы не хотели бы, чтобы счет отражал цену сейчас, но процесс во время счета, даже если это не имеет прямого отношения к тому, что там сейчас. В этом случае таблица Product может быть скорее справочной таблицей, чем истинным родительским дочерним отношением. Если вы храните все данные о продукте в таблице сведений о счете-фактуре, вам не нужен внешний ключ для продуктов, он нужен только для поиска активных продуктов во время размещения заказа. На самом деле, номер модели прошлой накладной может больше не быть в таблице продуктов, если поставщик изменил ее или полностью отбросил продукт. Но вы не хотели бы потерять данные о том, какие из этих продуктов были куплены в прошлом.
С другой стороны, если отношение требует, чтобы данные оставались согласованными с текущими значениями, формальный внешний ключ является лучшим методом.