В дополнение / повторение комментариев, я бы:
## Clients
ClientID
ParentClientID references Clients.ClientID
BillingAddressID references Addresses.AddressID
ContactAddressID references Addresses.AddressID
## Sites
SiteID
ClientID references Clients.ClientID
SiteAddressID references Addresses.AddressID
SiteManagerAddressID references Addresses.AddressId
## Addresses
AddressID
## Chargeables
SiteID references Sites.SiteID
## Payments
ClientID references Clients.ClientID
Поскольку кошение является повторяющимся явлением, запись в таблице сайта будет содержать запись о кошенном участке, месяце начала и окончания кошения в любом году и периодичности. Таблица сборов может вести себя как история всех оплачиваемых событий, происходящих на этом сайте, в том числе каждый раз, когда она косится (поэтому, если вы пропускаете неделю, вы не платите за нее и не пишете платную), а также дополнительные функции, такие как очистка от сорняков , очистка водосточных желобов, копка дренажа, стрижка живой изгороди и т. д. Если бы срезание живой изгороди происходило регулярно, я, вероятно, рекомендовал бы, чтобы конечный пользователь поместил другой сайт (может быть с тем же адресом) для обрезки живой изгороди, особенно если он был на периодическом цикле, отличном от кошения. Следовательно, может быть лучше назвать таблицу «Работа» сайта, если речь идет больше о работах, выполняемых на сайте, чем о самом сайте.
Если кошения являются неполными, можно сделать несколько платных записей, отражающих даты, на которые были проведены кошения, - может быть не важно записывать, что кошение было незавершенным, но если это так, возможно, платная запись без / будущей даты, как «занесенная в задачу» «? Состояние чьего-либо счета можно определить путем суммирования всех начисляемых сумм и всех платежей
Вы можете выбросить большинство из них, но основные рекомендации здесь:
- есть таблица адресов
- у многих других таблиц есть столбец XAddressID, где X является адресом
- вы можете даже иметь несколько адресов на клиента / сайт / что угодно, но дать им всем определенную цель ... вы можете сделать эту полностью свободную форму, но она добавляет ненужную сложность. Просто получите список всех видов адресов, которые необходимо отслеживать для каждой сущности, и укажите для них XAddressID
- сайты принадлежат клиентам и имеют адреса, где происходит кошение, у клиентов есть адреса, по которым отправляются счета
- клиенты могут существовать в иерархии, и выставление счетов может происходить на разных уровнях иерархии для работы сайта, имея собственную ссылку на таблицу клиентов и имея нулевой адрес биллинга или не позволяя вам отслеживать, где выставлять счета конкретному клиенту. Бизнес-правило «если адрес выставления счета нулевой, подниматься по иерархии до тех пор, пока не встретится ненулевое значение», может разрешить конечным уровням иерархии иметь свои собственные адреса выставления счетов, даже если узлы, расположенные ближе к корню, не имеют их и выставлены счет родительскому элементу
Учитывая сложность формирования адресов, о которой я говорил, вы действительно можете иметь таблицы Client, Address и ClientAddress (3 столбца, адресный адрес, клиентский адрес и адрес) и позволить клиенту вообще иметь любой тип адреса, просто поставив «Выставление счетов», «Экстренный контакт», «Переписка», «Дом управляющего», «Мать генерального директора» или что-то еще в столбце типа…, но есть две важные вещи, которые следует учитывать:
- люди не хотят такого большого выбора; это головная боль для них и головная боль для вас:
- если у вас есть некоторая программная зависимость от определенных типов адресов (экстренный контакт, выставление счетов), вам придется кодировать бизнес-правила, чтобы проверить, есть ли у каждого клиента эти два типа адресов в записи, особенно если поле полностью свободная форма.
Пользовательский интерфейс становится более сложным, так как вы должны предоставить список выбора нескольких адресов и т. Д.
«Выбери простое, а не идеальное решение»