Answer the question
In order to leave comments, you need to log in
Which object storage scheme to choose?
The project belongs to the real estate sector.
Each property strictly corresponds to one of the types: apartment, house, garage, etc.
Each property has certain common properties (address, area, price, etc.)
And there are properties that correspond only to a specific type of object (type - house: plot area, presence of a pool, etc.)
Now each type of object has a own table in the database (MySQL).
It lists both common properties for all objects and unique ones.
In the new version of the project, it is planned to increase the types of objects.
If you work according to the old scheme, then you need to add a lot of tables.
Many tables are inconvenient:
Answer the question
In order to leave comments, you need to log in
Store. for example, each property is a separate table with a link + a table of aggregated data for each object. So you get a selection of all objects by property + fast return of data. 5000 objects is not the number to bother about taking up space. And you can store links not in each table, but in a separate linking table. In other matters, I don’t see that there was any drawdown in speed even at 80 joins, if there is a primary key connection everywhere.
Actually, in the second option, you came to the EAV model, it is more universal, but at the same time slower than the classical one, requires more complex queries and is more difficult to control integrity.
Finished this site the other day. head-scratching stopped at eav with several types of fields
this is how it turned out
ads
category ads
common fields for ads from all categories
properties of categories property
values for ads
the main jamb of eav is that it’s impossible to select with one request depending on the filter settings, you have to collect IDs for each parameter and then intersect them, something like this
private function get_offers($page, $per_page)
{
$filter_fields = $this->get_current_filter_enabled_fields();
$filter_values = $this->s('@filter~:values_by_cats/' . $this->cat->id);
//
$offers_ids_sets = array();
$offers_extra_ids_sets = array();
if ($filter_values) {
foreach ($filter_values as $field_id => $data) {
if (isset($filter_fields[$field_id])) {
$field = $filter_fields[$field_id];
$prop = $field['prop'];
$common_prop = $field['common_prop'];
if ($prop) {
$type = $prop['type'];
if ($type == 'bool' && $data['value']) {
$offers_ids_sets[] = PropValue::where('prop_id', $prop['id'])
->where('bool_value', true)
->lists('offer_id')->toArray();
}
if ($type == 'strings_list' && isset($data['selected']) && !is_null($data['selected'])) {
$prop_settings = _j($prop['settings']);
if (isset($prop_settings['strings_list']['items'][$data['selected']])) {
$offers_ids_sets[] = PropValue::where('prop_id', $prop['id'])
->where('string_value', $prop_settings['strings_list']['items'][$data['selected']])
->lists('offer_id')->toArray();
}
}
if ($type == 'numbers_list' && isset($data['selected']) && !is_null($data['selected'])) {
$prop_settings = _j($prop['settings']);
if (isset($prop_settings['numbers_list']['items'][$data['selected']])) {
$offers_ids_sets[] = PropValue::where('prop_id', $prop['id'])
->where('number_value', $prop_settings['numbers_list']['items'][$data['selected']])
->lists('offer_id')->toArray();
}
}
if (($type == 'numbers_list' || $type == 'number') && isset($data['min']) && isset($data['max'])) {
$offers_ids_sets[] = PropValue::where('prop_id', $prop['id'])
->where('number_value', '>=', $data['min'])
->where('number_value', '<=', $data['max'])
->lists('offer_id')->toArray();
}
}
if ($common_prop) {
$type = $common_prop['type'];
if (($type == 'numbers_list' || $type == 'number') && isset($data['min']) && isset($data['max'])) {
$offers_ids_sets[] = OfferExtra
::where($common_prop['field'], '>=', $data['min'])
->where($common_prop['field'], '<=', $data['max'])
->lists('offer_id')->toArray();
}
}
}
}
}
$offers_ids = array();
if ($offers_ids_sets) {
$offers_ids = (array)$offers_ids_sets[0];
for ($i = 1; $i < count($offers_ids_sets); $i++) {
$offers_ids = array_intersect($offers_ids, (array)$offers_ids_sets[$i]);
}
}
//
$builder = $this->cat->offers();
if ($offers_ids_sets) {
$builder = $builder->whereIn('id', $offers_ids);
}
$builder = $builder->whereHas('extra', function ($builder) use ($offers_extra_ids_sets) {
$builder->where('enabled', true);
});
$count = $builder->count();
$offers = $builder->orderBy('created_at', 'DESC')->offset(($page - 1) * $per_page)->take($per_page)->get();
return array($count, $offers);
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question