EAV model, da ili ne?

poruka: 2
|
čitano: 1.473
|
moderatori: XXX-Man, vincimus
1
+/- sve poruke
ravni prikaz
starije poruke gore
17 godina
neaktivan
offline
EAV model, da ili ne?

Trebao bih uskoro krenuti s izradom baze podataka i trenutno se lomim ići na EAV model ili ne.

 

EAV mi se čini kao logičan izbor kada imam pred sobom zahtjev da se za jednog čovjeka mora bilježiti boja očiju, veličina nosa, broj cipela, težina, bračno stanje,... s tim da će se za par dana početi bilježiti i godina rođenja, broj djece. Uglavnom, zahtjev je da količina informacija koja se bilježi o korisnicima bude krajnje fleksibilna i da se nova obilježja mogu dodavati bez dodatnog programiranja.

Znači EAV je way-to-go, ali šta da radim kad se postavi zahtjev da se istovremeno korisnici mogu filtrirati po svim obilježjima, znači mora biti moguće pronaći sve neoženjene muškarce s velikim ušima. Query koji ovo traži je monstruozno kompliciran i spor.

 

Kako vi riješavate ovakve probleme?

 
0 0 hvala 0
17 godina
neaktivan
offline
Re: EAV model, da ili ne?
Kad kažeš bez dodatnog programiranja misliš na sve izvan baze?

Koliko entiteta misliš pratiti preko EAV tablica i koliko podataka? Jer ako je to neki razuman broj, sa indeksiranjem vjerojatno možeš dobiti dobre performanse.

Možeš možda uvesti dodatnu veznu tablicu EA-AV i mapiranja riješiti preko viewa i/ili porcedura? Tu možeš radi indeksiranja raditi mapiranja atributa na nekakve integere/hasheve (lupam na pamet).

Data Access ti je cjelokupno u bazi? Ako ne koristič ER maping, možeš pomoću starih DataSetova i SELECT * hendlati dodavanje atributa u tablicu, pa ti niti ne treba EAV model...
Ovo što si ti napisao je samo jedna tablica sa korisnicima koja očekuje dodavanje dodatnih atributa i u kodu opet to moraš hendlat na neki način.

Ovisi od scenarija do scenarija.

Što se tiče tvog upita...
Pretpostavimo da je ovakva tablica


CREATE TABLE EAV
( Entity VARCHAR(50),
EntityId INT,
Attribute VARCHAR(50),
Value SQL_VARIANT
);

CREATE CLUSTERED INDEX CI_EAV ON EAV (Entity,EntityId,Attribute)

INSERT INTO EAV VALUES ('Korisnik',1,'Ozenjen',1)
INSERT INTO EAV VALUES ('Korisnik',1,'VelikeUsi',1)
INSERT INTO EAV VALUES ('Korisnik',2,'Ozenjen',0)
INSERT INTO EAV VALUES ('Korisnik',2,'VelikeUsi',1)
INSERT INTO EAV VALUES ('Korisnik',3,'Ozenjen',1)
INSERT INTO EAV VALUES ('Korisnik',3,'VelikeUsi',0)
INSERT INTO EAV VALUES ('Korisnik',4,'Ozenjen',1)
INSERT INTO EAV VALUES ('Korisnik',4,'VelikeUsi',0)
INSERT INTO EAV VALUES ('Korisnik',5,'Ozenjen',1)
INSERT INTO EAV VALUES ('Korisnik',5,'VelikeUsi',1)
INSERT INTO EAV VALUES ('Korisnik',6,'Ozenjen',0)
INSERT INTO EAV VALUES ('Korisnik',6,'VelikeUsi',1)
INSERT INTO EAV VALUES ('Korisnik',7,'Ozenjen',0)
INSERT INTO EAV VALUES ('Korisnik',7,'VelikeUsi',1)
INSERT INTO EAV VALUES ('Korisnik',8,'Ozenjen',0)
INSERT INTO EAV VALUES ('Korisnik',8,'VelikeUsi',0)

INSERT INTO EAV VALUES ('Korisnik',7,'MaleNoge',1)
INSERT INTO EAV VALUES ('Korisnik',2,'MaleNoge',1)

--Brzo za lookup
--Index Seek Plan, Dynamic sql,...
SELECT e1.Entity,e1.EntityId,e1.Attribute,e1.Value,e2.Attribute,e2.Value,e3.Attribute,e3.Value
FROM EAV e1
JOIN EAV e2
ON e1.Entity = e2.Entity
AND e1.EntityId = e2.EntityId
JOIN EAV e3
ON e1.Entity = e3.Entity
AND e1.EntityId = e3.EntityId
WHERE e1.Entity = 'Korisnik'
AND (e1.Attribute = 'Ozenjen' AND e1.Value = 0)
AND (e2.Attribute = 'VelikeUsi' AND e2.Value = 1)
AND (e3.Attribute = 'MaleNoge' AND e2.Value = 1)

--Potencijalno brzo za sirok broj rezultata
--Clustered Scan svaki entitet mora imati sve atribute po kojima pretrazujemo unesene
SELECT *
FROM
(SELECT ROW_NUMBER() OVER (PARTITION BY EntityId ORDER BY (SELECT NULL) DESC) AS BrAtributa,EAV.* FROM EAV
WHERE
(Attribute = 'Ozenjen' AND Value = 0)
OR (Attribute = 'VelikeUsi' AND Value = 1)
OR (Attribute = 'MaleNoge' AND Value = 1)) AS stage
WHERE BrAtributa = 3



Gornji kod je specifičan sa MS SQL Server pošto koristi SQL_VARIANT tip. Ne znam za sigurno kako je to na ostalim bazama, ali vjerujem da je slično.
Ja sam tu probao dva tipa upita. Sa self joinovima i sa scanom EAV tablice.

Oba možes zamjeniti storom ili Table valued funkcijom. Broj parametara možeš mijenjati u stori tako da u porgramu nemaš nikakav dependency. Što točno selektiraš, ovisi o tebi..
Kad jednom pronađeš, entitete, lagano im dalje joinaš atribute koje želiš prikazati.

Priložio sam execution planove. S time, da vjerujem da se ovaj drugi upit još može optimirati, ali mi se ne da sad.
1
Nova poruka
E-mail:
Lozinka:
 
vrh stranice