Model EAV (Entity-Attribute-Value) - implementacja w Koseven Framework
Model EAV (Entity-Attribute-Value) to sposób przechowywania danych w bazie danych, w którym atrybuty są przechowywane jako wiersze w tabeli, a nie jako kolumny. Jest to szczególnie przydatne w sytuacjach, gdy liczba i rodzaj atrybutów dynamicznie się zmienia.
Zastosowania modelu EAV
Model EAV stosuje się w:
- Systemach zarządzania treścią (CMS), gdzie użytkownicy mogą dodawać własne pola do obiektów.
- Systemach medycznych, gdzie dane pacjentów są bardzo zróżnicowane.
- Aplikacjach e-commerce, gdzie różne produkty mają różne atrybuty.
- Bazach danych naukowych i eksperymentalnych, gdzie dane mogą mieć dynamiczne struktury.
Wady i zalety modelu EAV
Zalety:
- Elastyczność – pozwala na dodawanie nowych atrybutów bez zmiany schematu bazy danych.
- Oszczędność miejsca – unika pustych kolumn w bazie danych, gdy nie wszystkie obiekty mają te same atrybuty.
- Możliwość rozszerzania – łatwo dodać nowe typy atrybutów.
Wady:
- Skomplikowane zapytania SQL – konieczność łączenia wielu tabel.
- Problemy z indeksowaniem i wydajnością – trudniej zoptymalizować bazę danych.
- Brak kontroli typów – wartości atrybutów są często przechowywane jako tekst, co może prowadzić do błędów.
Implementacja modelu EAV w Koseven ORM
Poniżej przedstawiamy implementację modelu EAV w frameworku Koseven (Kohana 3.x) przy użyciu ORM.
Struktura tabel
CREATE TABLE entities (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL
);
CREATE TABLE attributes (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
type ENUM('int', 'float', 'string', 'bool') NOT NULL
);
CREATE TABLE entity_attributes (
id INT AUTO_INCREMENT PRIMARY KEY,
entity_id INT NOT NULL,
attribute_id INT NOT NULL,
value TEXT NOT NULL,
FOREIGN KEY (entity_id) REFERENCES entities(id),
FOREIGN KEY (attribute_id) REFERENCES attributes(id)
);
Modele w Koseven ORM
Model encji
class Model_Entity extends ORM {
protected $_table_name = 'entities';
protected $_has_many = [
'entity_attributes' => [
'model' => 'Entity_Attribute',
'foreign_key' => 'entity_id'
]
];
}
Model atrybutu
class Model_Attribute extends ORM {
protected $_table_name = 'attributes';
}
Model powiązań (EAV)
class Model_Entity_Attribute extends ORM {
protected $_table_name = 'entity_attributes';
protected $_belongs_to = [
'entity' => [
'model' => 'Entity',
'foreign_key' => 'entity_id'
],
'attribute' => [
'model' => 'Attribute',
'foreign_key' => 'attribute_id'
]
];
}
Przykład użycia
Dodawanie nowej encji i przypisanie jej atrybutów:
$entity = ORM::factory('Entity');
$entity->name = 'Produkt A';
$entity->save();
$attribute = ORM::factory('Attribute')->where('name', '=', 'Kolor')->find();
if (!$attribute->loaded()) {
$attribute->name = 'Kolor';
$attribute->type = 'string';
$attribute->save();
}
$entity_attribute = ORM::factory('Entity_Attribute');
$entity_attribute->entity_id = $entity->id;
$entity_attribute->attribute_id = $attribute->id;
$entity_attribute->value = 'Czerwony';
$entity_attribute->save();
Odczytanie wartości atrybutu dla encji:
$entity = ORM::factory('Entity', 1);
$attributes = $entity->entity_attributes->find_all();
foreach ($attributes as $attr) {
echo $attr->attribute->name . ': ' . $attr->value . "<br>";
}
Podsumowanie
Model EAV jest użyteczny w sytuacjach, gdy struktura danych jest dynamiczna, ale wiąże się z pewnymi problemami wydajnościowymi. W Koseven ORM można go zaimplementować poprzez odpowiednie modele i relacje. Wybór tego modelu powinien być jednak przemyślany, szczególnie w przypadku dużych zbiorów danych.