Как смоделировать различные критерии? - PullRequest
0 голосов
/ 05 августа 2009

Мне нужно иметь возможность сопоставить предполагаемых владельцев с брошенными животными, основываясь на разных критериях и местах.

У владельца будет установлен определенный критерий. Тип животного = "собака", порода = "Лабрадор ретривер", возраст должен быть от 1 до 5 лет, пол = кобель и т. Д. ...

Животное также будет иметь определенный набор критериев. Тип животного = "Собака", возраст = 3, пол = кобель, порода = "чихуахуа".

Животное также может быть: тип = "кошка", возраст = "12", пол = сука, порода = "тигр".

У меня также есть модель «Местоположение» как для владельца, так и для животного (полиморфная), которая содержит информацию, относящуюся к местонахождению животного или владельца.

Так что это легко ...

Сложная часть (по крайней мере для меня) - это когда мне нужно указать разные критерии для разных типов животных. Таким образом, животное типа = "собака" может иметь критерии "может принести?" в то время как у животного типа кошка могут быть критерии "без когтей"? и животное типа «рыба» может иметь критерии «узор» с несколькими вариантами [«крапчатый», «полосатый», «обычный»].

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

Опять же, это просто аналогия, потому что я не думаю, что моя настоящая проблема будет иметь какой-либо смысл для кого-то еще. Мне нужны только указатели в правильном направлении, может быть, ссылка или два. Я просто не могу понять, как сделать это в Rails без создания отдельной таблицы для каждого набора критериев, как в dog_criteria, cat_criteria, fish_criteria и т. Д. ...

Ответы [ 3 ]

1 голос
/ 05 августа 2009

Иногда для таких свойств мы прибегаем к простым парам имя / значение (или тройки имя / значение / тип). Это экономит добавление новых типов (и таблиц базы данных) для всех видов животных в мире. Или хуже для каждой породы: рассмотрите пуделей ... у них может быть дополнительное поле "декоративно выбритое" ... и сенбернар, емкость для бренди ...

0 голосов
/ 05 августа 2009

Решение для пары «имя-значение» можно выполнить в базе данных.

В этом примере 4 таблицы, персона, требование, домашнее животное, домашний питомец

Персона и Питомец имеют идентификатор и имя.
У каждого человека также есть одно или несколько требований. Требования имеют имя, сравнение и значение.
У каждого питомца есть один или несколько PetStats, которые состоят из имени и значения

с этой настройкой, можно найти короткошерстных собак с запросом вроде:

select * from pet, petstat
where pet.id = petstat.petId
 and petstat.name = 'hair'
 and petstat.value = 'short'
 and petId in (select petId from petstat
   where name='type' and value = 'dog')

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

select person.name, pet.name from person, pet 
where (select count(*) from requirement where requirement.personid = person.id)
 = (select  count(*) from requirement, petstat
    where requirement.comparison = 'eq' 
     and requirement.name = petstat.name
     and requirement.value = petstat.value
     and requirement.personId = person.id
     and petstat.petid = pet.id)
 + (select  count(*) from requirement, petstat
    where requirement.comparison = 'lt' 
     and requirement.name = petstat.name
     and requirement.value > petstat.value
     and requirement.personId = person.id
     and petstat.petid = pet.id)
 + (select  count(*) from requirement, petstat
    where requirement.comparison = 'gt' 
     and requirement.name = petstat.name
     and requirement.value < petstat.value
     and requirement.personId = person.id
     and petstat.petid = pet.id);

Сравнения «меньше» и «больше, чем» можно было бы лучше обрабатывать, добавляя числовые поля в таблицы требований и таблицы исходных данных и добавляя в запрос больше элементов, но это дает хорошую статистику.

Вот вставки для создания тестовых данных.

delete from person;
insert into person (id, name) values (1, 'Joe');
insert into person (id, name) values (2, 'Bill');
insert into person (id, name) values (3, 'Erik');
insert into person (id, name) values (4, 'Mike');

delete from pet;
insert into pet (id, name) values (1, 'spot');
insert into pet (id, name) values (2, 'mittens');
insert into pet (id, name) values (3, 'rover');

delete from requirement;
insert into requirement (personid, name, comparison, value) values (1, 'type', 'eq', 'dog');
insert into requirement (personid, name, comparison, value) values (1, 'color', 'eq', 'black');
insert into requirement (personid, name, comparison, value) values (2, 'type', 'eq', 'fish');
insert into requirement (personid, name, comparison, value) values (3, 'type', 'eq', 'dog');
insert into requirement (personid, name, comparison, value) values (3, 'hair', 'eq', 'long');

insert into requirement (personid, name, comparison, value) values (4, 'type', 'eq', 'dog');
insert into requirement (personid, name, comparison, value) values (4, 'weight', 'lt', '30');
insert into requirement (personid, name, comparison, value) values (4, 'weight', 'gt', '20');

delete from petstat;
insert into petstat (petId, name, value) values (1, 'type', 'dog');
insert into petstat (petId, name, value) values (1, 'color', 'black');
insert into petstat (petId, name, value) values (1, 'hair', 'short');
insert into petstat (petId, name, value) values (2, 'type', 'cat');

insert into petstat (petId, name, value) values (3, 'type', 'dog');
insert into petstat (petId, name, value) values (3, 'weight', '25');
insert into petstat (petId, name, value) values (3, 'color', 'brown');
0 голосов
/ 05 августа 2009

В мире моделирования программного обеспечения это, очевидно, будет сделано с помощью класса для каждого вида, т.е. «Собака», «Кошка», «Рыба», которые распространяют «Животное». В мире реляционных баз данных это становится немного сложнее представить.

Если вы хотите использовать этот объектно-ориентированный подход в своей базе данных, у вас будет таблица «Животные», а затем таблица для каждого вида: «Кошка», «Собака» и «Рыба». Тогда у вас, вероятно, будет таблица видов (или жестко запрограммированное перечисление в вашем коде), которая даст вам значение для размещения в строке «Животное», для какого вида было животное. Это скажет вам, как искать дополнительную информацию для каждого животного.

Это, вероятно, не лучший подход. То, что у вас есть, - это то, что я бы назвал «Пользовательские данные» для каждого животного. Вы должны определить одну таблицу со списком пользовательских атрибутов, а другую таблицу, чтобы сопоставить эти атрибуты со значением для каждой строки животных.

Если вы хотите, чтобы было удобнее видеть и контролировать, какие атрибуты могут применяться к каким видам, вы можете создать третью таблицу для «Категории», которая будет связана с видами животных и коллекцией атрибутов. Затем вы должны указать идентификатор категории в ряду животных.

Образцы таблиц:

Animals
-------
ID
Age
Sex
Species
Breed

Parameters
----------
ID
Name

Parameter Values
----------------
ParameterID
AnimalID
Value

Categories (optional - add CategoryID to animals)
---------------------
ID
Name

Category Parameters
-------------------
CategoryID
ParameterID
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...