Одиночное наследование или полиморфное?
Я программирую веб-сайт, который позволяет пользователям размещать объявления с подробными полями для различных типов товаров, которые они продают. Однако у меня есть вопрос о лучшей схеме базы данных.
На сайте есть много категорий (например, автомобили, компьютеры, камеры), и каждая категория объявлений имеет свои собственные поля. Например, у автомобилей есть такие атрибуты, как количество дверей, марка, модель и мощность, в то время как у компьютеров есть такие атрибуты, как ЦП, ОЗУ, модель материнской платы и т. Д.
Теперь, так как все они являются списками, я думал о полиморфном подходе, создавая родительскую таблицу LISTINGS и другую дочернюю таблицу для каждой из различных категорий (COMPUTERS, CARS, CAMERAS). Каждая дочерняя таблица будет иметь list_id, который будет ссылаться на таблицу LISTINGS. Таким образом, при получении списка он получит строку из LISTINGS, к которой присоединена связанная строка в связанной дочерней таблице.
LISTINGS
-listing_id
-user_id
-email_address
-date_created
-description
CARS
-car_id
-listing_id
-make
-model
-num_doors
-horsepower
COMPUTERS
-computer_id
-listing_id
-cpu
-ram
-motherboard_model
Является ли эта схема хорошим шаблоном проектирования или есть ли лучшие способы сделать это?
Я рассмотрел одиночное наследование, но быстро отмахнулся от мысли, потому что таблица станет слишком большой слишком быстро, но потом возникла еще одна дилемма - если пользователь выполняет глобальный поиск по всем спискам, то это означает, что мне придется опрашивать каждого ребенка стол отдельно. Что произойдет, если у меня будет более 100 различных категорий, не будет ли это неэффективным?
Я также подумал о другом подходе, где есть главная таблица (мета-таблица), которая определяет поля в каждой категории, и таблица полей, в которой хранятся значения полей каждого списка, но будет ли это противоречить нормализации базы данных?
Как на таких сайтах, как Kijiji?
2 ответа
Ваш дизайн базы данных в порядке. Нет причин менять то, что у тебя есть. Я видел, как поиск был сделан несколькими способами. Один из них заключается в том, чтобы ваша хранимая процедура поиска объединяла все таблицы, по которым нужно выполнять поиск, и индексировала столбцы для поиска. Второй способ, которым я видел, что он работал, который работал довольно хорошо, - это иметь таблицу, которая используется только для поиска, которая получает копию любых полей, которые нужно искать. Затем вы бы поместили триггеры в эти поля и обновили таблицу поиска.
У них обоих есть недостатки, но я предпочел первое второму.
РЕДАКТИРОВАТЬ
Вам нужны следующие таблицы.
Категории - Id - Описание
CategoriesListingsXref - CategoryId - ListingId
С помощью этой модели перекрестных ссылок вы можете объединить все свои списки для данной категории во время поиска. Затем добавьте немного динамического sql (потому что это легче понять) и создайте свой запрос, включив в него поля, по которым вы хотите выполнить поиск, и вызовите execute для вашего запроса.
Вот и все.
РЕДАКТИРОВАТЬ 2 Это, кажется, немного большее обсуждение, которое мы можем найти в этих полях для комментариев. Но все, что мы обсудим, можно понять, прочитав следующий пост. http://www.sommarskog.se/dyn-search-2008.html
Это действительно полный и показывает вам более чем 1 способ сделать это с за и против. Удачи.
Я думаю, что выбранный вами дизайн подойдет для сценария, который вы только что описали. Хотя я не уверен, должны ли таблицы подклассов иметь свой собственный идентификатор. Поскольку CAR является листингом, имеет смысл, что значения принадлежат одному и тому же "домену".
На типичном сайте классифицированных объявлений данные для объявления записываются один раз, а затем в основном только для чтения. Вы можете использовать это и хранить данные во втором наборе таблиц, которые более оптимизированы для поиска именно так, как вы хотите, чтобы пользователи искали. Кроме того, проблема поиска действительно существует только для "общего" поиска. Как только пользователь выберет определенный тип рекламы, вы можете переключиться на таблицы подклассов для более расширенного поиска (RAM > 4 ГБ, cpu = overpowered).