Самый простой способ создать это - иметь таблицу, которая содержит все допустимые комбинации почтового индекса и состояния, а затем использовать эти два столбца в качестве внешних ключей для таблицы, содержащей фактический адрес. Таким образом, любая недопустимая комбинация состояния / ZIP нарушит ограничение внешнего ключа. Этот подход будет работать, даже если почтовый индекс пересекает строки состояния, если вы не сделаете поле почтового индекса в таблице поиска уникальным ключом. Недостатком этого подхода является то, что вам необходимо предварительно заполнить таблицу поиска и поддерживать ее в актуальном состоянии, что будет означать оплату USPS за их списки.
Если вы действительно настаиваете на подходе «один штат на ZIP» и / или не хотите покупать список у USPS, вы все равно можете использовать аналогичный подход. Опять же, вам понадобится таблица соответствия с состоянием и ZIP, но на этот раз вы захотите сделать ZIP уникальным ключом. Поскольку записи добавляются в таблицу, содержащую адреса, вы можете использовать триггер для заполнения таблицы поиска, когда почтовый индекс еще не существует. Это добавит немного накладных расходов, но в большинстве случаев не будет достаточным для беспокойства.