Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > СУБД, общие вопросы > Замарочился со схемой данных для приложения


Автор: dimqw31 25.10.2010, 09:41
Здравствуйте уважаемые форумчане. Вот встал вопросик по поводу архитектуры будущего приложения.
Даже скорее архитектуры данных.
Стоит нетривиальная задача написать приложение которое бы при вводе наименований автомобильных запчастей
выводила бы марку (список марок) автомобиля в котором используются совместно больше двух любых введенных
пользователем запчастей (запчасти вводятся по номеру).


Например в автомобиле FORD FOCUS используются запчасти с номерами:
933-3883(запчасть 1),
933-8282(запчасть 2),
933-2932(запчасть 3)
933-2139(запчасть 4)
933-2235(запчасть 5)
и т.д.
В автомобиле FORD C-MAX используются запчасти с номерами:
933-3283(запчасть 1),
933-2932(запчасть 2),
933-1112(запчасть 3)
933-2235(запчасть 4)
и т.д.
В автомобиле FORD FUSION используются запчасти с номерами:
933-3283(запчасть 1),
933-2932(запчасть 2),
933-1112(запчасть 3)
и т.д.

Допустим пользователь выбрал запчасти с номерами 933-3283, 933-2932 и 933-1112.
Так как две и больше (в данном случае три) из этих запчастей вместе находятся только в автомобиле марки FORD FUSION, то и программа должна вернуть данную
марку на первом месте, а на втором FORD C-MAX (так как там совместно используется две запчасти) или список марок автомобилей(если эти запчасти также используются вместе). У запчасти есть еще такие атрибуты
как их количество в марке автомобиля (например 2 противотуманки или 3 плафона (в шт.)) и стоимость запчасти.
Еще проблема в том, что запрашивать данные можно разными способами:
1) просто ввести номера запчастей и программа должна выдать марки автомобилей где хотя бы половина выбранных пользователем
запчастей использовалась совместно (для начала хотя бы больше двух наименований)
2) ввести номера запчастей и их количество и программа должна вывести где хотя бы половина выбранных пользователем
запчастей использовалась совместно причем в заданных или меньших количествах (но не больше);
3) ввести номера запчастей и ввести денежную сумму, и программа должна выдать те марки автомобилей? где хотя бы половина
выбранных пользователем запчастей использовалась совместно и сумма их стоимости не превышала бы заданную стоимость.

Результаты надо выводить в зависимости в порядке содержания запчастей в автомобиле (в порядке убывания совместно используемых запчастей)
Также в программе должна быть возможность забивать данные в базу в виде МАРКА АВТО, НОМЕРА ЗАПЧАСТЕЙ В ЭТОМ АВТО, КОЛИЧЕСТВО ЗАПЧАСТЕЙ В ДАННОМ АВТО, ЦЕНА ЗАПЧАСТИ.

Вопрос в том, как организовать хранение данных в БД для удобного их извлечения и занесения, чтобы удобно было реализовать описанную выше логику.
Уже весь мозг себе вынес....
Пока придумал только табличку в виде: МАРКА АВТО, НОМЕРА ЗАПЧАСТЕЙ КОТОРЫЕ ЕСТЬ В ЭТОМ АВТО. А далее full-text search по
этой табличке (по колонке с номерами запчастей) и вывод марки авто. Правда непонятно куда приделать количество и стоимость запчастей.....???
Буду рад если найдется умный человек и поможет со схемой данных для данной интересной задачки.. Не могу понять какие таблички
использовать и в какой конфигурации.. А если кто приведет примеры запросов к этим табличкам так я вообще от счастья в окно выпрыгну.
Просто реально уже башку над этим сломал.... 

Автор: Zloxa 25.10.2010, 10:01
Цитата(dimqw31 @  25.10.2010,  09:41 Найти цитируемый пост)
МАРКА АВТО, НОМЕРА ЗАПЧАСТЕЙ КОТОРЫЕ ЕСТЬ В ЭТОМ АВТО

И что вас смущает в этой структуре? Что заставляет Вас думать, что данная структура Вам не подходит?
Вообще классически задача решалась бы так. Таблица автомобилей, таблица зап-частей автомобилей, таблица используемости запчасти в автомобиле.(stfg http://www.google.ru/search?sourceid=chrome&ie=UTF-8&q=%D0%BD%D0%BE%D1%80%D0%BC%D0%B0%D0%BB%D0%B8%D1%86%D0%B7%D0%B0%D1%86%D0%B8%D1%8F#hl=ru&newwindow=1&sa=X&ei=DCnFTK7yHoXtOeHZyMwL&ved=0CCgQBSgA&q=%D0%BD%D0%BE%D1%80%D0%BC%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F&spell=1&fp=6849a794dad57d0e)
Однако в целом ряде частных случаев, пользуясь бритвой оккамы, можно свести и все к одной, денормализованной таблице, как в Вашем случае.
Цитата(dimqw31 @  25.10.2010,  09:41 Найти цитируемый пост)
Правда непонятно куда приделать количество и стоимость запчастей.....???

что мешает прилепить туда же?
Цитата(dimqw31 @  25.10.2010,  09:41 Найти цитируемый пост)
А далее full-text search по
этой табличке

Сомнительно, что в данном случае необходимо задействовать full-text. Обычного индекса, с лихвой должно бы хватить.
Цитата(dimqw31 @  25.10.2010,  09:41 Найти цитируемый пост)
1) просто ввести номера запчастей и программа должна выдать марки автомобилей где хотя бы половина выбранных пользователем
запчастей использовалась совместно (для начала хотя бы больше двух наименований)

Код

select МАРКА_АВТО 
from ТАБЛИЦА 
group by МАРКА_АВТО 
having count(*)/2 >= count(case when НОМЕРА_ЗАПЧАСТЕЙ in ('запчасть1','запчасть2'...,'запчастьN') then 1 end)

Автор: dimqw31 26.10.2010, 11:38
Еще один ламерский вопросик...

При внесении данных с формы мне придется вносить сразу  в три таблицы?
номер запчасти в одну таблицу
марку машины в другую
и количество запчастей в машине в третью (которая и реализуют отношение многие-ко-многим)

Автор: Zloxa 26.10.2010, 12:05
Можно и из одной  формы сразу в три таблицы, но обычно делают три формы. В одной правят автомобили, в другой - запчасти, в третьей - связи.

Автор: dimqw31 26.10.2010, 12:49
Цитата(Zloxa @ 25.10.2010,  10:01)
Цитата(dimqw31 @  25.10.2010,  09:41 Найти цитируемый пост)
МАРКА АВТО, НОМЕРА ЗАПЧАСТЕЙ КОТОРЫЕ ЕСТЬ В ЭТОМ АВТО

И что вас смущает в этой структуре? Что заставляет Вас думать, что данная структура Вам не подходит?
Вообще классически задача решалась бы так. Таблица автомобилей, таблица зап-частей автомобилей, таблица используемости запчасти в автомобиле.(stfg http://www.google.ru/search?sourceid=chrome&ie=UTF-8&q=%D0%BD%D0%BE%D1%80%D0%BC%D0%B0%D0%BB%D0%B8%D1%86%D0%B7%D0%B0%D1%86%D0%B8%D1%8F#hl=ru&newwindow=1&sa=X&ei=DCnFTK7yHoXtOeHZyMwL&ved=0CCgQBSgA&q=%D0%BD%D0%BE%D1%80%D0%BC%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F&spell=1&fp=6849a794dad57d0e)
Однако в целом ряде частных случаев, пользуясь бритвой оккамы, можно свести и все к одной, денормализованной таблице, как в Вашем случае.
Цитата(dimqw31 @  25.10.2010,  09:41 Найти цитируемый пост)
Правда непонятно куда приделать количество и стоимость запчастей.....???

что мешает прилепить туда же?
Цитата(dimqw31 @  25.10.2010,  09:41 Найти цитируемый пост)
А далее full-text search по
этой табличке

Сомнительно, что в данном случае необходимо задействовать full-text. Обычного индекса, с лихвой должно бы хватить.
Цитата(dimqw31 @  25.10.2010,  09:41 Найти цитируемый пост)
1) просто ввести номера запчастей и программа должна выдать марки автомобилей где хотя бы половина выбранных пользователем
запчастей использовалась совместно (для начала хотя бы больше двух наименований)

Код

select МАРКА_АВТО 
from ТАБЛИЦА 
group by МАРКА_АВТО 
having count(*)/2 >= count(case when НОМЕРА_ЗАПЧАСТЕЙ in ('запчасть1','запчасть2'...,'запчастьN') then 1 end)



а как можно сделать  так чтобы в выражении IN запчасти брались не с условием OR, а с условием AND.. ?

Автор: Zloxa 26.10.2010, 12:55
Цитата(dimqw31 @  26.10.2010,  12:49 Найти цитируемый пост)
а как можно сделать  так чтобы в выражении IN запчасти брались не с условием OR, а с условием AND.. ?

Вам это не нужно. Поразмыслите внимательнее.
Одна запчасть не может быть одновременно и той и другой, а условие применяется к одной запчасти.

Добавлено через 3 минуты и 55 секунд
PS В былые времена за оверквотинг очень больно били. Сейчас времена попроще. Но злоупотреблять этим все равно не стоит. Старайтесь цитировать только то, что имеет смысл цитировать. Все цитировать - не надо.

Автор: dimqw31 26.10.2010, 13:44
Цитата(Zloxa @ 26.10.2010,  12:55)
Вам это не нужно. Поразмыслите внимательнее.
Одна запчасть не может быть одновременно и той и другой, а условие применяется к одной запчасти.

Извиняюсь, я наверное не правильно сформулировал часть задачки, а потом соответственно и вопросы
не правильные начал задавать. Дело в том, что существует не только условие на количество запчастей в машине, но еще у каждой запчасти есть свой числовой атрибут (не важен физический смысл), который разный в каждой марке машины.. Похоже именно этот атрибут (числовой) нужно мне хранить в третьей связующей таблице..

Автор: Zloxa 26.10.2010, 14:03
Цитата(dimqw31 @  26.10.2010,  13:44 Найти цитируемый пост)
 Похоже именно этот атрибут (числовой) нужно мне хранить в третьей связующей таблице.. 

Эта фраза создает ощущение, что у Вас существенно прибавилось в понимании основ. Это радует.

Автор: dimqw31 26.10.2010, 18:55
Цитата(Zloxa @ 26.10.2010,  14:03)
Эта фраза создает ощущение, что у Вас существенно прибавилось в понимании основ. Это радует.

Похоже да, но оказалось не совсем....
Наконец-то сделал нужную модель данных..
Но тут возник новый вопросик
У меня в запросе есть условие WHERE (имя столбца) IN ('значение1', 'значение2', 'значение3' и т.д.)
Как можно сделать, чтобы запрос искал вхождения НЕ  'значение1' OR 'значение2' OR  'значение3' 
а  'значение1' AND  'значение2' AND  'значение3'.
Вообщем значения у меня хранятся в коллекции, а нужно вывести строки БД, в которых
одновременно находились все значения коллекции или хотя бы 3 из 4 (или 2 из 4)
 
Пример:
    name        number
 значение1       2
 значение2       2 
 значение3       2
 значение4       2
 значение5       3
 значение4       3
 значение6       3
 значение1       4
 значение2       4
 значение3       4

запрос..........
WHERE  name IN  ('значение1', 'значение2', 'значение3', 'значение4')

В результате должен вывести:
number
   2
   4

Автор: Zloxa 26.10.2010, 20:19
Код

select number from table 
group by humber 
having 4 = count(case when name IN  ('значение1', 'значение2', 'значение3', 'значение4') then 1 end)

Однако ж, мне думается, что если заведомо надо выполнять искать подобного рода поисковые запросы, на сколь нибдуь значимые объемы, то чтото не то с дизайном приложения.

Автор: dimqw31 26.10.2010, 21:38
Цитата(Zloxa @ 26.10.2010,  20:19)

Однако ж, мне думается, что если заведомо надо выполнять искать подобного рода поисковые запросы, на сколь нибдуь значимые объемы, то чтото не то с дизайном приложения.

Да в принципе не очень большие объемы, значений будет в среднем около 10-15, а number около 10000

Добавлено через 11 минут и 3 секунды
Цитата(Zloxa @ 26.10.2010,  20:19)
[codhaving 4 = count(case when name IN  ('значение1', 'значение2', 'значение3', 'значение4') then 1 end)
[/code]


А это стандартный код SQL?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)