Необходимо создать таблицу с множеством атрибутов, которые должны быть доступны для поиска по SQL - PullRequest
5 голосов
/ 18 января 2011

Я в затруднении. Я создаю сайт бронирования жилья, и клиенту требуется средство поиска, позволяющее посетителям осуществлять поиск и фильтровать свойства по критериям. Дело в том, что его список критериев очень длинный, в основном логические значения и вычисляемые значения, например:

Ванная комната, балкон, курение, алкоголик, максимальное количество человек, кабельное телевидение, интернет, ковровое покрытие, кондиционер, центральное отопление, обслуживание в номерах и т. Д., И т. Д., И т. Д. ...

Я думаю о необходимости создать поле для каждого из них, но есть очень большой шанс, что число предпочтений может даже возрасти. Я отказался от идеи хранить все в сериализованном объекте в виде строки, так как тогда было бы невозможно выполнить поиск с использованием SQL-запроса. Есть ли у меня какие-либо варианты, кроме настройки отдельных полей для каждого предпочтения здесь?

Спасибо. Я использую PHP MySQL.

Ответы [ 5 ]

5 голосов
/ 18 января 2011

Не могли бы вы иметь таблицу «многие ко многим», которая связывает идентификатор свойства со справочной таблицей, имеющей атрибуты? Таблица поиска будет содержать строку для каждого атрибута, который имеет свойство?

Основной стол

ID PropertyName OtherCols

10 CottageA Stuff

20 CottageB OtherStuff

Атрибуты

100 Курение

200 Кондиционер

300 Обслуживание номеров

400 ТВ

500 Интернет

Таблица поиска

ID AttributeID

10 100

10 200

10 300

20 100

20 400

20 500

1 голос
/ 18 января 2011

Вы можете сделать сопоставление, как предлагалось ранее, но включить значение в сопоставление

Стол отеля

create table hotel_table (
 id int(4) unsigned not null auto_increment primary key,
 hotel_name varchar(40) not null,
 ...other row info
);

Критерии отеля

create table hotel_criteria (
 id int(4) unsigned not null auto_increment primary key,
 criteria_name varchar(40) not null
);

Карта отеля Критерии

create table hotel_criteria_map (
 id int(4) unsigned not null auto_increment primary key,
 hotel_id int(4) unsigned not null,
 criteria_id int(4) unsigned not null,
 string_data varchar(20) null, #use this to add in extra string information for criteria
 decimal_data decimal(6,2) null, #use this to add in extra decimal information for criteria
 #... either of the above or other extra info, just giving examples ...
 unique key (hotel_id,criteria_id),
 foreign key (hotel_id) references hotel_table(id),
 foreign key (criteria_id) references hotel_criteria(id)
);

Затем вы можете выбрать эти значения:

select * from hotel_table where id={your hotel id}; #hotel info

select m.*,c.criteria_name from hotel_criteria_map m, hotel_criteria c where m.criteria_id=c.id and hotel_id={your hotel id}; #criteria info

Возможно, есть лучший способ сделать это, но только предложение. Вы могли бы ввести критерии для определенного отеля на карту, только если он относится к этому определенному отелю (по существу, не имеет каких-либо строк карты критериев, которые будут иметь значение 0).

1 голос
/ 18 января 2011

Я бы предложил создать поле для каждого критерия.Это позволит вам иметь самую быструю возможность поиска.При этом вы всегда можете создать TEXT или MEDIUMTEXT и сохранить JSON в этом поле.Таким образом, вы можете использовать json_encode для массива, такого как:

$amenities['bathroom'] = 1;
$amenities['balcony'] = 1;
$amenities['smoking'] = 0;

Тогда, если вы ищете дом с балконом, вы можете сделать:

SELECT * FROM `homes` WHERE `json_field` LIKE '%balcony: 1%'

И вместо LIKEвы всегда можете использовать поиск FULLTEXT, если у вас есть такая возможность на вашем сервере.

1 голос
/ 18 января 2011

Я сделал точно такой же поиск пару лет назад по каталогу отелей.Для этого мы использовали BitMask, например, , мы сохранили одно число, представляющее все возможные значения , например,

HotelTable 
ID Name         …    Features
 1 SuperHotel   …    5

Features
ID Name
 1 Balcony
 2 Shower
 4 Barrier-Free
 8 Whatever
 … …

.4 + 1).

Хотя это работало хорошо, я не уверен, что справлюсь с этим снова.По сути, все эти функции аналогичны тегам, поэтому вы также можете использовать известные подходы для создания таблицы тегов.

0 голосов
/ 18 января 2011

Вы должны прочитать о нормализации базы данных.IMHO, цель состоит в том, чтобы структурировать ваши таблицы таким образом, чтобы эти запросы выполнялись эффективно и с меньшим количеством логики на стороне php.Например, если с каждым из вышеупомянутых критериев поиска есть значение, связанное с ними, значения должны быть сохранены в отдельной таблице, и, если существует множество опций для многих значений, вам нужно будет установить другой тип отношений.Этот первый раз, когда вы будете смотреть на базу данных со всех сторон, вы сэкономите много php-кода, и, возможно, предотвратите полное перестроение базы данных, как только вы поймете, что у вас узкое место.Надеюсь, это было вообще полезно.Удачи!

...