= Релационен модел = == ER дијаграм == [[Image(EDB.svg, 1200px)]] == Описна документација и аргументација == === Сегмент: `Person` → `Candidate` / `Voter` === `Person` е централна базна табела која ги чува основните персонални податоци: `name`, `surname`, `date_of_birth`, `gender`. И `Candidate` и `Voter` наследуваат личност преку странски клуч `person_id`. Причина за ваквото моделирање: истото лице може да биде гласач во еден изборен циклус, а кандидат во друг. Исто така, кандидатот е граѓанин со право на глас, па еден `person_id` може истовремено да постои и во `Candidate` и во `Voter` табелата. Со централизирање на личните податоци во `Person` се избегнува редундантност и се осигурува конзистентност на податоците низ целата база. === Сегмент: `PoliticalParty` → `PartyLeader` === Лидерот на партијата е издвоен во посебна табела `PartyLeader` наместо да биде директен атрибут во `PoliticalParty`. Причина: лидерот е `Person` со свои персонални податоци, а лидерството се менува низ времето. Оваа структура овозможува историско следење на кој бил лидер на која партија и во кој период, без губење на историски записи. === Сегмент: `PoliticalParty` → `PartyCoalition` → `CoalitionMember` === Коалициите се моделирани преку посебен ентитет `PartyCoalition` поврзан со конкретен избор преку `election_id`. Членовите на коалицијата се евидентираат преку асоцијативната табела `CoalitionMember`. Причина: коалицискиот состав може да се менува меѓу изборни циклуси. Моделот овозможува прецизно следење кои партии биле дел од коалиција на кои конкретни избори, со можност за историска споредба. === Сегмент: `PoliticalEntity` === `PoliticalEntity` е генерички ентитет кој унифицирано претставува партија, коалиција или независен кандидат. Атрибутот `type` го разликува случајот, додека `party_id`, `coalition_id` и `candidate_id` се nullable во зависност од типот. Атрибутот `is_independent` го означува случајот кога кандидатот настапува без партиска припадност. Причина: табелите `VoteResult`, `Ballot`, `CandidateList` и `ElectionParticipant` се поврзуваат со еден унифициран ентитет наместо со три различни табели. Ова ја поедноставува аналитиката и ги намалува JOIN операциите при пребарување. === Сегмент: `Election` → `ElectionType` / `WinnerMethod` / `ElectionCycle` === Изборот е поврзан со три независни lookup табели: * `ElectionType` — дефинира тип на избор (парламентарни, претседателски, локални итн.) * `WinnerMethod` — дефинира метод на одредување победник (мнозински, пропорционален итн.) * `ElectionCycle` — овозможува моделирање на повеќе изборни круга во рамките на ист избор Причина: со издвојување на овие атрибути во посебни табели, моделот станува целосно генеричен. Истата структура се користи за секаков тип на избори, во која било земја, без потреба од структурни промени во базата. === Сегмент: `Region` → `RegionType` / `ElectoralDistrict` / `PollingStation` === `Region` е хиерархиски организирана преку self-referencing атрибут `parent_region_id`, со што се моделираат различни административни нивоа: * Земја * Регион * Општина * Населено место `RegionType` го дефинира нивото на регионот. `ElectoralDistrict` го поврзува регионот со конкретен избор и ги чува достапните места (`seats_available`), а `PollingStation` ги евидентира физичките гласачки места со адреса и број на регистрирани гласачи. Причина: хиерархискиот self-referencing дизајн на `Region` овозможува флексибилна примена за различни државни административни структури без промена на шемата. === Сегмент: `Ballot` / `VoteResult` === `Ballot` претставува евиденција на поединечно издадено гласачко ливче — поврзано со избор, гласачко место, политички ентитет и кандидат, со временска ознака (`ballot_timestamp`) и индикатор за валидност (`is_valid`). `VoteResult` претставува збирен резултат по гласачко место и политички ентитет, со вкупен број гласови (`votes`). Причина за раздвојувањето: `Ballot` овозможува детална ревизија и верификација на секое ливче, додека `VoteResult` овозможува брза аналитика и генерирање на резултати без процесирање на секој индивидуален запис. Клучно е да се напомене дека `Ballot` намерно не е поврзан со `Person`, со што тајноста на гласањето е загарантирана на ниво на дизајн на базата. === Сегмент: `CandidateList` / `CandidateListItem` === `CandidateList` ја поврзува листата на кандидати со конкретен избор и политички ентитет. `CandidateListItem` го евидентира секој кандидат на листата со неговата позиција (`position`). Причина: редоследот на кандидатите на изборна листа е правно релевантен при пропорционален систем на гласање. Со атрибутот `position` се овозможува прецизна евиденција на редоследот, а структурата поддржува листи со произволен број кандидати. === Сегмент: `StationElection` / `ElectionParticipant` === `StationElection` е асоцијативна табела која поврзува гласачко место со конкретен избор, бидејќи едно гласачко место може да биде активно на повеќе различни избори. `ElectionParticipant` ги евидентира политичките ентитети кои учествуваат во конкретна изборна единица (`district_id`), овозможувајќи прецизен приказ кој учесник настапил во кој дел на земјата.