Skip to content

Latest commit

 

History

History
497 lines (351 loc) · 15.3 KB

File metadata and controls

497 lines (351 loc) · 15.3 KB

Database Schema - Matrikkel Integration

Siste oppdatering: 22. oktober 2025
Flyway Baseline: V1__baseline_schema.sql
Database: PostgreSQL 17


Oversikt

Databasen inneholder 14 tabeller opprettet av baseline migration (V1__baseline_schema.sql). Skjemaet støtter full relasjonell integritet med foreign keys, indexes for ytelse, og inheritance-strategi for personer.

Baseline Migration Strategi

Prosjektet bruker en baseline migration tilnærming:

  • V1__baseline_schema.sql: Konsolidert skjema med alle 14 tabeller
  • Erstatter tidligere V1-V9 migrasjoner
  • Optimalisert for nye installasjoner
  • Inkluderer deprecated tabeller for bakoverkompatibilitet

Tabeller

1. matrikkel_matrikkelenheter

Formål: Matrikkelenheter (grunndata for eiendomsregisteret)

Primærnøkkel: matrikkel_matrikkelenhet_id (BIGINT, fra API)
Business Key: (kommunenummer, gardsnummer, bruksnummer, festenummer, seksjonsnummer)

Kolonner

Kolonne Type Nullable Beskrivelse
matrikkel_matrikkelenhet_id BIGINT NOT NULL Unik ID fra Matrikkel API
kommunenummer INTEGER NOT NULL 4-sifret kommunenummer (f.eks. 4601=Bergen)
gardsnummer INTEGER NOT NULL Gårdsnummer
bruksnummer INTEGER NOT NULL Bruksnummer
festenummer INTEGER NOT NULL Festenummer (0 hvis ikke aktuelt)
seksjonsnummer INTEGER NOT NULL Seksjonsnummer (0 hvis ikke seksjonert)
matrikkelnummer_tekst VARCHAR(50) NOT NULL Komplett matrikkelnummer som tekst
historisk_oppgitt_areal DOUBLE PRECISION Historisk oppgitt areal
areal_kilde VARCHAR(100) Kilde for areal-måling
tinglyst BOOLEAN Registrert i tinglysingsregisteret
skyld DOUBLE PRECISION Skyldverdi
bruksnavn VARCHAR(255) Bruksnavn/gårdsnavn
etableringsdato DATE Etableringsdato
er_seksjonert BOOLEAN Er seksjonert eiendom
har_aktive_festegrunner BOOLEAN Har aktive festegrunner
har_anmerket_klage BOOLEAN Har anmerket klage
har_grunnforurensing BOOLEAN Har grunnforurensing
har_kulturminne BOOLEAN Har kulturminne
utgatt BOOLEAN Utgått/avregistrert
nymatrikulert BOOLEAN Nymatrikulert
sist_lastet_ned TIMESTAMP NOT NULL Når record sist ble lastet ned

Indexer

CREATE INDEX idx_matrikkelenheter_kommunenummer ON matrikkel_matrikkelenheter(kommunenummer);
CREATE UNIQUE INDEX idx_matrikkelenheter_unique ON matrikkel_matrikkelenheter(
    kommunenummer, gardsnummer, bruksnummer, festenummer, seksjonsnummer
);

2. matrikkel_personer

Formål: Personer (base-tabell for inheritance-hierarki)

Primærnøkkel: id (BIGSERIAL, JPA auto-generated)
API ID: matrikkel_person_id (BIGINT, fra API)
Inheritance: Single Table Inheritance med person_type discriminator

Kolonner

Kolonne Type Nullable Beskrivelse
id BIGSERIAL NOT NULL JPA auto-generated primary key
matrikkel_person_id BIGINT NOT NULL Person ID fra Matrikkel API
person_type VARCHAR(31) NOT NULL Discriminator: 'FysiskPerson' eller 'JuridiskPerson'
nummer VARCHAR(20) KRITISK: Personnummer ELLER organisasjonsnummer!
navn VARCHAR(255) Navn (person eller organisasjon)
sist_lastet_ned TIMESTAMP NOT NULL Når record sist ble lastet ned

Indexer

CREATE UNIQUE INDEX idx_personer_matrikkel_person_id ON matrikkel_personer(matrikkel_person_id);
CREATE INDEX idx_personer_nummer ON matrikkel_personer(nummer);
CREATE INDEX idx_personer_type ON matrikkel_personer(person_type);

VIKTIG: nummer-feltet inneholder både personnummer OG organisasjonsnummer! Ikke bruk subclass-felter (fodselsnummer, organisasjonsnummer) - de er NULL!


3. matrikkel_fysiske_personer

Formål: Fysiske personer (extends Person)

Join: fysisk_person_entity_idmatrikkel_personer.id

Kolonner

Kolonne Type Nullable Beskrivelse
fysisk_person_entity_id BIGINT NOT NULL FK til matrikkel_personer.id
fodselsnummer VARCHAR(11) ⚠️ DEPRECATED: Alltid NULL! Bruk personer.nummer

Constraint

ALTER TABLE matrikkel_fysiske_personer 
ADD CONSTRAINT fk_fysisk_person_entity 
FOREIGN KEY (fysisk_person_entity_id) REFERENCES matrikkel_personer(id);

4. matrikkel_juridiske_personer

Formål: Juridiske personer/organisasjoner (extends Person)

Join: juridisk_person_entity_idmatrikkel_personer.id

Kolonner

Kolonne Type Nullable Beskrivelse
juridisk_person_entity_id BIGINT NOT NULL FK til matrikkel_personer.id
organisasjonsnummer VARCHAR(9) ⚠️ DEPRECATED: Alltid NULL! Bruk personer.nummer
organisasjonsform VARCHAR(100) Organisasjonsform (AS, ASA, etc.)

Constraint

ALTER TABLE matrikkel_juridiske_personer 
ADD CONSTRAINT fk_juridisk_person_entity 
FOREIGN KEY (juridisk_person_entity_id) REFERENCES matrikkel_personer(id);

5. matrikkel_eierforhold

Formål: Eierforhold (linking table mellom matrikkelenhet og eier)

Primærnøkkel: eierforhold_id (BIGSERIAL)

Kolonner

Kolonne Type Nullable Beskrivelse
eierforhold_id BIGSERIAL NOT NULL Auto-generated primary key
matrikkelenhet_id BIGINT NOT NULL FK til matrikkel_matrikkelenheter
fysisk_person_id BIGINT FK til matrikkel_personer (fysisk person)
juridisk_person_entity_id BIGINT FK til matrikkel_personer (juridisk person)
andel_teller INTEGER Andel teller (f.eks. 1 i 1/2)
andel_nevner INTEGER Andel nevner (f.eks. 2 i 1/2)
sist_lastet_ned TIMESTAMP NOT NULL Når record sist ble lastet ned
person_owner_id BIGINT ⚠️ DEPRECATED: Bruk fysisk_person_id
juridisk_person_owner_id BIGINT ⚠️ DEPRECATED: Bruk juridisk_person_entity_id
matrikkelenhet_owner_id BIGINT ⚠️ DEPRECATED: Ikke i bruk

Constraints

ALTER TABLE matrikkel_eierforhold 
ADD CONSTRAINT fk_eierforhold_matrikkelenhet 
FOREIGN KEY (matrikkelenhet_id) REFERENCES matrikkel_matrikkelenheter(matrikkel_matrikkelenhet_id);

ALTER TABLE matrikkel_eierforhold 
ADD CONSTRAINT fk_eierforhold_fysisk_person 
FOREIGN KEY (fysisk_person_id) REFERENCES matrikkel_personer(id);

ALTER TABLE matrikkel_eierforhold 
ADD CONSTRAINT fk_eierforhold_juridisk_person 
FOREIGN KEY (juridisk_person_entity_id) REFERENCES matrikkel_personer(id);

Indexer

CREATE INDEX idx_eierforhold_matrikkelenhet ON matrikkel_eierforhold(matrikkelenhet_id);
CREATE INDEX idx_eierforhold_fysisk_person ON matrikkel_eierforhold(fysisk_person_id);
CREATE INDEX idx_eierforhold_juridisk_person ON matrikkel_eierforhold(juridisk_person_entity_id);

6. matrikkel_bygninger

Formål: Bygninger knyttet til matrikkelenheter

Primærnøkkel: bygning_id (BIGINT, fra API)

Kolonner

Kolonne Type Nullable Beskrivelse
bygning_id BIGINT NOT NULL Unik ID fra Matrikkel API
bygningsnummer BIGINT Bygningsnummer
kommunenummer INTEGER Kommunenummer
bygningstype VARCHAR(100) Type bygg
bebygd_areal DOUBLE PRECISION Bebygd areal (m²)
naerings_kode VARCHAR(50) Næringskode
sist_lastet_ned TIMESTAMP NOT NULL Når record sist ble lastet ned

7. matrikkel_bruksenheter

Formål: Bruksenheter (boliger, næringslokaler)

Primærnøkkel: bruksenhet_id (BIGINT, fra API)

Kolonner

Kolonne Type Nullable Beskrivelse
bruksenhet_id BIGINT NOT NULL Unik ID fra Matrikkel API
bruksenhetsnummer VARCHAR(20) Bruksenhetsnummer (H0101, etc.)
bygning_id BIGINT FK til matrikkel_bygninger
matrikkelenhet_id BIGINT FK til matrikkel_matrikkelenheter
bruksenhetstype VARCHAR(100) Type bruksenhet (bolig, næring, etc.)
bruksareal DOUBLE PRECISION Bruksareal (m²)
antall_rom INTEGER Antall rom
kjokken_type VARCHAR(50) Kjøkkentype
bad_wc_type VARCHAR(50) Bad/WC-type
sist_lastet_ned TIMESTAMP NOT NULL Når record sist ble lastet ned

Constraints

ALTER TABLE matrikkel_bruksenheter 
ADD CONSTRAINT fk_bruksenhet_bygning 
FOREIGN KEY (bygning_id) REFERENCES matrikkel_bygninger(bygning_id);

ALTER TABLE matrikkel_bruksenheter 
ADD CONSTRAINT fk_bruksenhet_matrikkelenhet 
FOREIGN KEY (matrikkelenhet_id) REFERENCES matrikkel_matrikkelenheter(matrikkel_matrikkelenhet_id);

8. matrikkel_veger

Formål: Veger/gater (må lastes FØR adresser!)

Primærnøkkel: veg_id (BIGINT, fra API)

Kolonner

Kolonne Type Nullable Beskrivelse
veg_id BIGINT NOT NULL Unik ID fra Matrikkel API
adressenavn VARCHAR(255) Vegnavn
kommunenummer INTEGER Kommunenummer
sist_lastet_ned TIMESTAMP NOT NULL Når record sist ble lastet ned

KRITISK: Veger må lastes FØR adresser fordi vegadresser har foreign key til veger!


9. matrikkel_adresser

Formål: Adresser (base-tabell for inheritance)

Primærnøkkel: adresse_id (BIGINT, fra API)
Inheritance: Single Table Inheritance med adresse_type discriminator

Kolonner

Kolonne Type Nullable Beskrivelse
adresse_id BIGINT NOT NULL Unik ID fra Matrikkel API
adresse_type VARCHAR(31) NOT NULL Discriminator: 'Vegadresse' eller 'Matrikkeladresse'
kommunenummer INTEGER Kommunenummer
sist_lastet_ned TIMESTAMP NOT NULL Når record sist ble lastet ned

10. matrikkel_vegadresser

Formål: Vegadresser (extends Adresse)

Join: vegadresse_entity_idmatrikkel_adresser.adresse_id

Kolonner

Kolonne Type Nullable Beskrivelse
vegadresse_entity_id BIGINT NOT NULL FK til matrikkel_adresser.adresse_id
veg_id BIGINT FK til matrikkel_veger.veg_id
husnummer INTEGER Husnummer
bokstav VARCHAR(1) Bokstav (A, B, C, etc.)

Constraints

ALTER TABLE matrikkel_vegadresser 
ADD CONSTRAINT fk_vegadresse_adresse 
FOREIGN KEY (vegadresse_entity_id) REFERENCES matrikkel_adresser(adresse_id);

ALTER TABLE matrikkel_vegadresser 
ADD CONSTRAINT fk_vegadresse_veg 
FOREIGN KEY (veg_id) REFERENCES matrikkel_veger(veg_id);

Deprecated Tabeller (Bakoverkompatibilitet)

Disse tabellene er erstattet av matrikkel_eierforhold, men inkludert for bakoverkompatibilitet:

11. matrikkel_matrikkelenhet_owners

12. matrikkel_person_owners

13. matrikkel_juridisk_person_owners

Status: Deprecated - bruk matrikkel_eierforhold i stedet!


14. flyway_schema_history

Formål: Flyway migration tracking

Automatisk opprettet av Flyway for å spore hvilke migrasjoner som er kjørt.


Entity Relationships

matrikkel_matrikkelenheter (1) ←──── (N) matrikkel_eierforhold
                                           ├── (1) matrikkel_personer (fysisk_person_id)
                                           └── (1) matrikkel_personer (juridisk_person_entity_id)

matrikkel_personer (1) ←──── (1) matrikkel_fysiske_personer
matrikkel_personer (1) ←──── (1) matrikkel_juridiske_personer

matrikkel_bygninger (1) ←──── (N) matrikkel_bruksenheter ──── (1) matrikkel_matrikkelenheter

matrikkel_veger (1) ←──── (N) matrikkel_vegadresser ──── (1) matrikkel_adresser

Eksempel-spørringer

Finn alle matrikkelenheter eid av person/org

SELECT m.matrikkelnummer_tekst, p.navn, e.andel_teller, e.andel_nevner
FROM matrikkel_eierforhold e
JOIN matrikkel_matrikkelenheter m ON e.matrikkelenhet_id = m.matrikkel_matrikkelenhet_id
JOIN matrikkel_personer p ON (e.fysisk_person_id = p.id OR e.juridisk_person_entity_id = p.id)
WHERE p.nummer = '964965226'  -- personnummer eller organisasjonsnummer
ORDER BY m.matrikkelnummer_tekst;

Tell matrikkelenheter per kommune

SELECT kommunenummer, COUNT(*) as antall
FROM matrikkel_matrikkelenheter
GROUP BY kommunenummer
ORDER BY antall DESC;

Finn adresser for matrikkelenhet

SELECT v.adressenavn, va.husnummer, va.bokstav
FROM matrikkel_bruksenheter b
JOIN matrikkel_vegadresser va ON va.vegadresse_entity_id = b.bruksenhet_id
JOIN matrikkel_veger v ON va.veg_id = v.veg_id
WHERE b.matrikkelenhet_id = 123456;

Statistikk for alle tabeller

SELECT 
    schemaname,
    tablename,
    pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS size,
    (SELECT COUNT(*) FROM information_schema.tables t 
     WHERE t.table_name = tablename) as row_count
FROM pg_tables
WHERE schemaname = 'public'
AND tablename LIKE 'matrikkel_%'
ORDER BY tablename;

Migrasjons-prosess

Første gangs oppsett

# 1. Last environment variables
export $(grep -v '^#' .env | xargs)

# 2. Kjør Flyway baseline migration
mvn flyway:migrate

# 3. Verifiser at 14 tabeller ble opprettet
psql -h $DB_HOST -p $DB_PORT -U $DB_USERNAME -d $DB_NAME -c "\dt"

Verifiser migrasjons-status

mvn flyway:info

Forventet output:

+-----------+---------+------------------+------+---------------------+---------+
| Category  | Version | Description      | Type | Installed On        | State   |
+-----------+---------+------------------+------+---------------------+---------+
| Versioned | 1       | baseline schema  | SQL  | 2025-10-21 12:00:00 | Success |
+-----------+---------+------------------+------+---------------------+---------+

Viktige Merknader

1. Person.nummer er Universell

KRITISK: Både personnummer OG organisasjonsnummer lagres i matrikkel_personer.nummer!

// ❌ FEIL - Disse feltene er NULL!
fysiskPerson.getFodselsnummer();
juridiskPerson.getOrganisasjonsnummer();

// ✅ RIKTIG - Bruk base-tabell
person.getNummer();

2. Veger Må Lastes Først

AdresseMapper krever at Veg-entiteter eksisterer i database:

// ✅ RIKTIG rekkefølge:
fetchAndSaveVegData(kommunenummer);        // 1. Last veger
fetchAndSaveAdresseData(matrikkelenheter); // 2. Last adresser

3. Deprecated Felter

Tabellen matrikkel_eierforhold inneholder deprecated felter for bakoverkompatibilitet:

  • person_owner_id → bruk fysisk_person_id
  • juridisk_person_owner_id → bruk juridisk_person_entity_id
  • matrikkelenhet_owner_id → ikke i bruk

Database Maintenance

Vacuum og Analyze

-- Etter store imports
VACUUM ANALYZE matrikkel_matrikkelenheter;
VACUUM ANALYZE matrikkel_personer;
VACUUM ANALYZE matrikkel_eierforhold;

Reindex

-- Ved ytelsesproblem
REINDEX TABLE matrikkel_matrikkelenheter;

Dokumentasjon


Lisens

Dette prosjektet er utviklet for integrasjon med Kartverkets Matrikkel API.